CVE-2026-1294

All In One Image Viewer Block <= 1.0.2 - Unauthenticated Server-Side Request Forgery via image-proxy Endpoint

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

Description

The All In One Image Viewer Block plugin for WordPress is vulnerable to Server-Side Request Forgery in all versions up to, and including, 1.0.2 due to missing authorization and URL validation on the image-proxy REST API endpoint. This makes it possible for unauthenticated attackers to make web requests to arbitrary locations originating from the web application and 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: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.0.2
PublishedFebruary 4, 2026
Last updatedFebruary 5, 2026
Affected pluginimage-viewer

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan focuses on exploiting the **Server-Side Request Forgery (SSRF)** vulnerability in the **All In One Image Viewer Block** plugin (version <= 1.0.2). --- ### 1. Vulnerability Summary The vulnerability exists in the plugin's implementation of a REST API endpoint designed to act as a…

Show full research plan

This research plan focuses on exploiting the Server-Side Request Forgery (SSRF) vulnerability in the All In One Image Viewer Block plugin (version <= 1.0.2).


1. Vulnerability Summary

The vulnerability exists in the plugin's implementation of a REST API endpoint designed to act as an image proxy. The endpoint image-proxy (likely registered under the image-viewer/v1 namespace) fails to implement any authorization checks (permission_callback) and does not validate or sanitize the target URL. Consequently, any unauthenticated user can force the WordPress server to make HTTP requests to arbitrary internal or external destinations.

2. Attack Vector Analysis

  • Endpoint: /wp-json/image-viewer/v1/proxy (inferred namespace based on slug image-viewer).
  • Method: GET (most likely for a proxy) or POST.
  • Vulnerable Parameter: url or src (inferred).
  • Authentication: None (Unauthenticated).
  • Preconditions: The REST API must be enabled (default in WordPress).
  • Impact: SSRF allows scanning internal ports, accessing internal services (e.g., AWS metadata at 169.254.169.254, local Redis/Memcached), and potentially bypassing firewalls.

3. Code Flow (Inferred)

  1. Registration: The plugin uses the rest_api_init hook to register a route using register_rest_route().
  2. Missing Check: The permission_callback is either omitted (defaults to public in older WP versions) or explicitly set to __return_true.
  3. The Sink: The handler function for this route retrieves a URL from the request parameters (e.g., $request->get_param('url')).
  4. Request Execution: The handler passes this URL directly into a function like wp_remote_get() or file_get_contents() without validating that the host is an authorized remote image provider or preventing access to localhost/private IP ranges.
  5. Output: The content retrieved from the target URL is returned to the attacker in the HTTP response.

4. Nonce Acquisition Strategy

According to the vulnerability description, this is an unauthenticated SSRF. Custom REST API endpoints in WordPress often do not require a nonce if they are intended for public-facing frontend components or if the developer neglected security.

If the endpoint does require a wp_rest nonce for unauthenticated users:

  1. Identify Shortcode: The plugin slug is image-viewer. The shortcode/block is likely image-viewer.
  2. Create Page: wp post create --post_type=page --post_status=publish --post_content='<!-- wp:image-viewer/viewer {"url":"..."} /-->' (The exact block name can be found via wp plugin get image-viewer --field=name).
  3. Navigate: Use browser_navigate to view the page.
  4. Extract Nonce: Use browser_eval to search for localized script data.
    • Search for wp-api, imageViewerData, or similar: browser_eval("window.wpApiSettings?.nonce").

Note: If the description "unauthenticated" is accurate, the endpoint should be reachable directly without a nonce via the http_request tool.

5. Exploitation Strategy

We will attempt to use the WordPress server to query its own internal service.

Step 1: Identify the exact REST Route
The agent should first list available routes to confirm the namespace.

  • Tool: http_request
  • URL: http://localhost:8080/wp-json/
  • Action: Search the response for "image-viewer" and "proxy".

Step 2: Execute SSRF (Internal File/Service Access)
Once the endpoint is confirmed (assumed here to be /wp-json/image-viewer/v1/proxy), attempt to access the local web server.

  • Tool: http_request
  • Method: GET
  • URL: http://localhost:8080/wp-json/image-viewer/v1/proxy?url=http://127.0.0.1:8080
  • Payload (Alternative if POST): {"url": "http://127.0.0.1:8080"}
  • Expected Response: The HTML source code of the WordPress homepage (proving the server talked to itself).

Step 3: Port Scanning (Confirmation of Impact)
Try to access a closed port vs. an open port to see if the response timing or error message changes.

  • URL: http://localhost:8080/wp-json/image-viewer/v1/proxy?url=http://127.0.0.1:22 (Check for SSH banner).

6. Test Data Setup

  1. Install Plugin: Ensure image-viewer version 1.0.2 is installed and active.
  2. Internal Target: No special target is needed; the WordPress instance itself at http://127.0.0.1:8080 serves as the "internal service."
  3. Identify Block Name: Run grep -r "register_block_type" . in the plugin directory to find the exact block name if a page needs to be created.

7. Expected Results

  • Successful Exploitation: An unauthenticated GET request to the proxy endpoint returns the body of the target URL provided in the url parameter.
  • Response Headers: The response may contain Content-Type: image/... if the plugin tries to spoof the content type, but the body will contain the target's data.

8. Verification Steps

  1. Check Access Logs: Access the Docker container logs to see if a request originated from 127.0.0.1 to the WordPress home page at the exact time the exploit was triggered.
    • tail -f /var/log/apache2/access.log (or equivalent).
  2. Compare Responses: Verify that the body returned by the proxy matches the body of a direct request to the target URL.

9. Alternative Approaches

  • Parameter Names: If url fails, try src, image, path, or href.
  • Bypassing Basic Filters: If the plugin has weak filters (e.g., checking for "http"), try:
    • https://127.0.0.1:8080
    • http://0.0.0.0:8080
    • http://localhost:8080
  • Protocol Fuzzing: Check if the plugin supports file:// or gopher:// (though wp_remote_get usually restricts these).
    • Target: url=file:///etc/passwd (to check for Local File Read via SSRF).
Research Findings
Static analysis — not yet PoC-verified

Summary

The All In One Image Viewer Block plugin for WordPress is vulnerable to Unauthenticated Server-Side Request Forgery (SSRF) via its image-proxy REST API endpoint. The plugin fails to perform authorization checks and does not validate the destination of the target URL, allowing attackers to proxy requests to internal network services or bypass access controls.

Vulnerable Code

// The specific file and line numbers are inferred based on standard WordPress REST API implementations

// Likely registration in a file like class-image-viewer-rest.php
add_action( 'rest_api_init', function () {
    register_rest_route( 'image-viewer/v1', '/proxy', array(
        'methods'             => 'GET',
        'callback'            => 'image_viewer_proxy_handler',
        'permission_callback' => '__return_true', // Missing authorization
    ) );
} );

---

// Likely handler implementation
function image_viewer_proxy_handler( $request ) {
    $url = $request->get_param( 'url' );
    
    // Vulnerable: No validation of the URL destination
    $response = wp_remote_get( $url );

    if ( is_wp_error( $response ) ) {
        return $response;
    }

    $body = wp_remote_retrieve_body( $response );
    $type = wp_remote_retrieve_header( $response, 'content-type' );

    header( "Content-Type: $type" );
    echo $body;
    exit;
}

Security Fix

--- a/includes/class-image-viewer-rest.php
+++ b/includes/class-image-viewer-rest.php
@@ -10,7 +10,9 @@
    register_rest_route( 'image-viewer/v1', '/proxy', array(
        'methods'             => 'GET',
        'callback'            => 'image_viewer_proxy_handler',
-       'permission_callback' => '__return_true',
+       'permission_callback' => function () {
+           return current_user_can( 'edit_posts' );
+       },
    ) );
 });
 
 function image_viewer_proxy_handler( $request ) {
    $url = $request->get_param( 'url' );
-   $response = wp_remote_get( $url );
+   if ( ! wp_http_validate_url( $url ) ) {
+       return new WP_Error( 'invalid_url', 'Invalid URL provided.', array( 'status' => 400 ) );
+   }
+   $response = wp_remote_get( $url, array( 'reject_unsafe_urls' => true ) );

Exploit Outline

The exploit targets the unauthenticated REST API endpoint registered by the plugin. 1. Endpoint Discovery: An attacker identifies the REST API route, typically located at `/wp-json/image-viewer/v1/proxy`. 2. Payload Construction: The attacker prepares a GET request with a `url` query parameter pointing to a sensitive internal resource. Examples include: - Internal Metadata: `http://localhost:8080/wp-json/image-viewer/v1/proxy?url=http://169.254.169.254/latest/meta-data/` (for AWS/Cloud environments). - Local Service Access: `http://localhost:8080/wp-json/image-viewer/v1/proxy?url=http://127.0.0.1:8080/wp-admin/`. - Port Scanning: Testing various internal IPs and ports to identify open services. 3. Execution: No authentication or nonces are required. A simple cURL request or browser navigation to the crafted URL will trigger the server to fetch and return the content of the target URL to the attacker.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.