[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fEsMv6I3MxP-rst6CQul2nWTqBhYUVtkaXEA-GI7FkYo":3},{"id":4,"url_slug":5,"title":6,"description":7,"plugin_slug":8,"theme_slug":9,"affected_versions":10,"patched_in_version":11,"severity":12,"cvss_score":13,"cvss_vector":14,"vuln_type":15,"published_date":16,"updated_date":17,"references":18,"days_to_patch":20,"patch_diff_files":21,"patch_trac_url":9,"research_status":28,"research_verified":29,"research_rounds_completed":30,"research_plan":31,"research_summary":9,"research_vulnerable_code":9,"research_fix_diff":9,"research_exploit_outline":9,"research_model_used":32,"research_started_at":33,"research_completed_at":34,"research_error":9,"poc_status":9,"poc_video_id":9,"poc_summary":9,"poc_steps":9,"poc_tested_at":9,"poc_wp_version":9,"poc_php_version":9,"poc_playwright_script":9,"poc_exploit_code":9,"poc_has_trace":29,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":29,"source_links":35},"CVE-2026-0688","webmention-authenticated-subscriber-server-side-request-forgery","Webmention \u003C= 5.6.2 - Authenticated (Subscriber+) Server-Side Request Forgery","The Webmention plugin for WordPress is vulnerable to Server-Side Request Forgery in all versions up to, and including, 5.6.2 via the 'Tools::read' function. This makes it possible for authenticated attackers, with Subscriber-level access and above, to make web requests to arbitrary locations originating from the web application and can be used to query and modify information from internal services.","webmention",null,"\u003C=5.6.2","5.7.0","medium",6.4,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:L\u002FUI:N\u002FS:C\u002FC:L\u002FI:L\u002FA:N","Server-Side Request Forgery (SSRF)","2026-04-01 19:17:16","2026-04-02 07:39:35",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F02c9beba-dfa5-4a30-8355-62ff9a2630f7?source=api-prod",1,[22,23,24,25,26,27],"includes\u002Fclass-avatar-store.php","includes\u002Fclass-comment-walker.php","includes\u002Fclass-tools.php","includes\u002Fhandler\u002Fclass-mf2.php","includes\u002Fhandler\u002Fclass-wp.php","readme.md","researched",false,3,"# Exploitation Research Plan: CVE-2026-0688 (Webmention SSRF)\n\n## 1. Vulnerability Summary\nThe **Webmention** plugin for WordPress is vulnerable to an authenticated Server-Side Request Forgery (SSRF) via the `Tools::read` function. The vulnerability exists because the plugin registers a REST API endpoint that accepts a user-provided `source` URL and fetches it without sufficient validation or restriction to external addresses. This allows a user with at least `Subscriber` permissions (the `read` capability) to cause the server to make requests to internal services or arbitrary external locations.\n\n## 2. Attack Vector Analysis\n- **REST API Endpoint:** `wp-json\u002Fwebmention\u002F1.0\u002Fparse`\n- **HTTP Method:** `GET` (as defined by `WP_REST_Server::READABLE` in `Tools::register_routes`)\n- **Vulnerable Parameter:** `source`\n- **Required Parameter:** `target` (must be a valid URL, but is not the primary SSRF target)\n- **Authentication:** Required (Subscriber-level access).\n- **Capability Check:** `current_user_can( 'read' )` in the `permission_callback`.\n- **Encryption\u002FNonce:** Requires a standard WordPress REST API nonce (`_wpnonce`) for authenticated requests.\n\n## 3. Code Flow\n1. **Route Registration:** In `includes\u002Fclass-tools.php`, the `Tools::register_routes` function registers the `\u002Fparse` route. It sets the `permission_callback` to `current_user_can( 'read' )`, which is granted to all logged-in users, including Subscribers.\n2. **Request Handling:** When a GET request is made to `\u002Fwp-json\u002Fwebmention\u002F1.0\u002Fparse`, the `Tools::read` function is executed.\n3. **Parameter Extraction:** `Tools::read` extracts the `source` and `target` parameters from the `$request` object.\n4. **The Sink:** The code calls `Request::get( $source, false )`. \n   - Based on the plugin architecture, `Webmention\\Request::get` performs a remote HTTP request (likely using `wp_remote_get`) to the provided `$source` URL.\n5. **Processing (Post-Request):** The response is then passed to a `Handler` which attempts to parse it (e.g., using Microformats or the WordPress API handler). Even if parsing fails, the initial request to the internal\u002Farbitrary IP has already been made.\n\n## 4. Nonce Acquisition Strategy\nThe REST API requires a `wp_rest` nonce for authenticated sessions. \n\n1. **Setup:** Create a Subscriber user and log in.\n2. **Page Navigation:** Navigate to any standard WordPress page (like the Dashboard or Homepage).\n3. **Extraction:** Use `browser_eval` to extract the REST nonce from the `wpApiSettings` object, which is standard in WordPress for localized REST data.\n   - **JS Expression:** `window.wpApiSettings?.nonce`\n4. **Alternative:** If `wpApiSettings` is not available, the agent can check the page source for `_wpnonce` in scripts or the `X-WP-Nonce` header in link tags.\n\n## 5. Exploitation Strategy\nThe goal is to demonstrate that the server can be forced to reach an internal resource (e.g., `http:\u002F\u002F127.0.0.1` or a metadata service).\n\n### Step-by-Step Plan:\n1. **User Creation:** Create a user with the `subscriber` role using WP-CLI.\n2. **Authentication:** Log in as the Subscriber.\n3. **Nonce Retrieval:** Navigate to `\u002Fwp-admin\u002F` and execute `browser_eval(\"window.wpApiSettings.nonce\")` to get the REST nonce.\n4. **Request Injection:**\n   - **Target:** `http:\u002F\u002Flocalhost:8080\u002Fwp-json\u002Fwebmention\u002F1.0\u002Fparse`\n   - **Method:** `GET`\n   - **Query Parameters:**\n     - `source`: `http:\u002F\u002F127.0.0.1:80` (or another internal IP\u002Fport)\n     - `target`: `https:\u002F\u002Fexample.com` (required for validation but secondary)\n     - `_wpnonce`: `[EXTRACTED_NONCE]`\n5. **Request Execution:** Use the `http_request` tool to perform the GET request.\n\n### Expected Payload (HTTP Request):\n```http\nGET \u002Fwp-json\u002Fwebmention\u002F1.0\u002Fparse?source=http:\u002F\u002F127.0.0.1:80&target=https:\u002F\u002Fexample.com&_wpnonce=a1b2c3d4e5 HTTP\u002F1.1\nHost: localhost:8080\nCookie: [SUBSCRIBER_COOKIES]\n```\n\n## 6. Test Data Setup\n1. **Target Internal Content:** Ensure there is something to \"hit\" internally. The easiest target is the WordPress instance itself on `127.0.0.1:80`.\n2. **User:**\n   ```bash\n   wp user create attacker attacker@example.com --role=subscriber --user_pass=password123\n   ```\n3. **Plugin State:** Ensure the Webmention plugin is active.\n   ```bash\n   wp plugin activate webmention\n   ```\n\n## 7. Expected Results\n- **Success Condition:** The server attempts to fetch the `source` URL. If targeting a running service (like the local WP instance), the REST API might return a structured response from the parsing handler (e.g., in `MF2` or `WP` mode).\n- **JSON Response:** A successful (though perhaps empty) JSON object containing parsed fields.\n- **Error Response:** If the internal service returns something non-HTML, the `Handler` might return a `WP_Error` with `no_api_link` (from `class-wp.php`), but the `Request::get` call will have already completed the SSRF.\n\n## 8. Verification Steps\n1. **Log Observation:** If possible, check the access logs of the service at the `source` IP to see a request originating from the WordPress server's IP.\n2. **Response Analysis:**\n   - If `source` is an internal WordPress site, look for responses that include details from that site's REST API, indicating the `WP` handler (`includes\u002Fhandler\u002Fclass-wp.php`) successfully navigated from the initial URL to the site's API root.\n3. **Blind Verification:** If no output is returned, use an OOB (Out-Of-Band) interaction service (like Webhook.site) as the `source` and verify the hit.\n\n## 9. Alternative Approaches\n- **Aggregated Mode:** Set `mode=aggregated` in the query string to trigger the `parse_aggregated` path in `Tools::read`.\n- **Targeting Metadata:** On cloud environments, target `http:\u002F\u002F169.254.169.254\u002Flatest\u002Fmeta-data\u002F` to demonstrate high-impact data exposure.\n- **Protocol Smuggling:** Attempt `gopher:\u002F\u002F` or `file:\u002F\u002F` if the underlying `Request::get` wrapper doesn't strictly enforce `http(s)`. (Though `esc_url_raw` usually limits this).","gemini-3-flash-preview","2026-04-17 21:53:54","2026-04-17 21:54:36",{"type":36,"vulnerable_version":37,"fixed_version":11,"vulnerable_browse":38,"vulnerable_zip":39,"fixed_browse":40,"fixed_zip":41,"all_tags":42},"plugin","5.6.2","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwebmention\u002Ftags\u002F5.6.2","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fwebmention.5.6.2.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwebmention\u002Ftags\u002F5.7.0","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fwebmention.5.7.0.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwebmention\u002Ftags"]