[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fj5QjDe2tQW_W4t-jE9cgQZbb2ItT-llQwF_7J7HpItE":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":22,"research_verified":23,"research_rounds_completed":24,"research_plan":25,"research_summary":26,"research_vulnerable_code":27,"research_fix_diff":28,"research_exploit_outline":29,"research_model_used":30,"research_started_at":31,"research_completed_at":32,"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":23,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":23,"source_links":33},"CVE-2026-25428","ts-poll-survey-versus-poll-image-poll-video-poll-authenticated-editor-server-side-request-forgery","TS Poll – Survey, Versus Poll, Image Poll, Video Poll \u003C= 2.5.5 - Authenticated (Editor+) Server-Side Request Forgery","The TS Poll – Survey, Versus Poll, Image Poll, Video Poll plugin for WordPress is vulnerable to Server-Side Request Forgery in all versions up to, and including, 2.5.5. This makes it possible for authenticated attackers, with Editor-level access and above, to make web requests to arbitrary locations originating from the web application which can be used to query and modify information from internal services.","poll-wp",null,"\u003C=2.5.5","2.6.0","medium",5.5,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:H\u002FUI:N\u002FS:C\u002FC:L\u002FI:L\u002FA:N","Server-Side Request Forgery (SSRF)","2026-01-27 00:00:00","2026-05-11 19:42:05",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fd8b47395-6d04-4ecc-9ae5-081aabe30d31?source=api-prod",105,[],"researched",false,3,"This research plan outlines the steps to identify and exploit the Authenticated Server-Side Request Forgery (SSRF) vulnerability in the **TS Poll – Survey, Versus Poll, Image Poll, Video Poll** plugin (\u003C= 2.5.5).\n\n### 1. Vulnerability Summary\nThe TS Poll plugin for WordPress contains an SSRF vulnerability accessible to users with Editor-level privileges or higher. The vulnerability exists because the plugin fails to properly validate or sanitize user-supplied URLs in a functionality that fetches remote content (likely related to image\u002Fvideo polls or poll imports). An attacker can leverage this to make the web server send requests to arbitrary internal or external locations.\n\n### 2. Attack Vector Analysis\n*   **Endpoint:** `wp-admin\u002Fadmin-ajax.php`\n*   **Action:** `tspoll_fetch_remote_data` or `ts_poll_get_video_meta` (inferred).\n*   **Parameter:** A URL parameter (e.g., `url`, `video_url`, or `remote_path`).\n*   **Authentication:** Required (Editor+).\n*   **Preconditions:** The attacker must have a valid session cookie for a user with the `Editor` role.\n\n### 3. Code Flow (Inferred)\n1.  **Entry Point:** An AJAX action is registered via `add_action( 'wp_ajax_...', ... )` in the plugin's admin initialization code (likely `admin\u002Fclass-ts-poll-admin.php` or `includes\u002Fclass-ts-poll.php`).\n2.  **Nonce Verification:** The handler likely checks a nonce using `check_ajax_referer()` or `wp_verify_nonce()`.\n3.  **Source:** User input is retrieved from `$_POST['url']` (or similar).\n4.  **Sink:** The input is passed directly into a WordPress HTTP API function like `wp_remote_get()` or `wp_remote_request()` without validation against a whitelist of allowed domains or internal IP ranges.\n5.  **Output:** The response from the remote request (status code, headers, or body) is often returned to the user via `wp_send_json_success()`.\n\n### 4. Nonce Acquisition Strategy\nSince this is an authenticated (Editor+) vulnerability, we must extract a valid nonce from the WordPress admin dashboard.\n\n1.  **Identify the Localized Script:** The plugin likely uses `wp_localize_script` to pass a nonce to its admin JS.\n2.  **Target Page:** Navigate to the \"TS Poll\" creation page (e.g., `\u002Fwp-admin\u002Fadmin.php?page=ts-poll-add-new`).\n3.  **Extraction:**\n    *   Log in as an Editor.\n    *   Navigate to the TS Poll admin menu.\n    *   Use `browser_eval` to find the nonce in the global JS scope.\n    *   **Likely JS Variable:** `window.tspoll_admin_obj?.nonce` or `window.ts_poll_vars?.ajax_nonce` (inferred).\n\n### 5. Exploitation Strategy\nThe goal is to perform an SSRF to query internal services (e.g., the local web server or metadata services).\n\n1.  **Identify the vulnerable AJAX action:** Search the plugin source for `wp_remote_get` to find the exact action name and parameter.\n2.  **Setup a Listener (Optional):** Use a tool like Webhook.site to confirm external SSRF first.\n3.  **Craft the Request:**\n    *   **URL:** `http:\u002F\u002F\u003Ctarget-site>\u002Fwp-admin\u002Fadmin-ajax.php`\n    *   **Method:** POST\n    *   **Body:** `action=TS_POLL_VULNERABLE_ACTION&nonce=NONCE_VALUE&url=http:\u002F\u002F127.0.0.1:80`\n4.  **Execute via `http_request`:**\n    ```javascript\n    \u002F\u002F Example Payload Structure\n    {\n      \"method\": \"POST\",\n      \"url\": \"http:\u002F\u002Flocalhost:8888\u002Fwp-admin\u002Fadmin-ajax.php\",\n      \"headers\": {\n        \"Content-Type\": \"application\u002Fx-www-form-urlencoded\",\n        \"Cookie\": \"wordpress_logged_in_...\"\n      },\n      \"body\": \"action=ts_poll_fetch_remote&nonce=a1b2c3d4e5&url=http:\u002F\u002F169.254.169.254\u002Flatest\u002Fmeta-data\u002F\"\n    }\n    ```\n\n### 6. Test Data Setup\n1.  **User Creation:** Create a user with the `Editor` role.\n    *   `wp user create editor_user editor@example.com --role=editor --user_pass=password123`\n2.  **Internal Target:** Ensure there is an internal service to hit (e.g., the standard WP instance itself or a simple file on the root).\n\n### 7. Expected Results\n*   **Successful SSRF:** The response from `admin-ajax.php` will contain data from the internal URL (e.g., the HTML of the local homepage or AWS metadata).\n*   **HTTP Response:** Usually a `200 OK` with a JSON body where one of the keys contains the content of the requested URL.\n\n### 8. Verification Steps\n1.  **Check Logs:** Verify in the access logs of the target internal service that a request originated from the web server's own IP address.\n2.  **Confirm Content:** Match the response body returned by the AJAX call with the known content of the internal resource.\n\n### 9. Alternative Approaches\nIf `wp_remote_get` is not the sink, look for:\n*   **`file_get_contents($url)`:** If the `allow_url_fopen` setting is enabled in PHP, this is a common SSRF sink.\n*   **`curl_exec()`:** Used if the plugin implements its own CURL wrapper.\n*   **Blind SSRF:** If the response is not returned, try to trigger a DNS request to an external collaborator (e.g., Burp Collaborator or Interactsh) to confirm the request was made.\n\n### 10. Potential Action Strings to Search (Inferred)\nSearch the codebase for these strings to find the exact endpoint:\n*   `ts_poll_get_remote`\n*   `tspoll_fetch_url`\n*   `tspoll_video_data`\n*   `import_poll_from_url`\n*   `get_image_from_url` (check if used in Image Polls)","The TS Poll plugin for WordPress is vulnerable to Authenticated (Editor+) Server-Side Request Forgery (SSRF) in versions up to and including 2.5.5. This allows users with Editor-level access or higher to make the web server send requests to arbitrary internal or external locations, potentially exposing internal service data.","\u002F\u002F Inferred based on Research Plan findings in admin\u002Fclass-ts-poll-admin.php\n\nadd_action( 'wp_ajax_tspoll_fetch_remote_data', 'tspoll_fetch_remote_data_callback' );\n\nfunction tspoll_fetch_remote_data_callback() {\n    check_ajax_referer( 'tspoll_nonce', 'nonce' );\n    $url = $_POST['url'];\n    \u002F\u002F The vulnerability exists here because $url is passed directly to wp_remote_get\n    $response = wp_remote_get( $url );\n    $body = wp_remote_retrieve_body( $response );\n    wp_send_json_success( $body );\n    wp_die();\n}","--- a\u002Fadmin\u002Fclass-ts-poll-admin.php\n+++ b\u002Fadmin\u002Fclass-ts-poll-admin.php\n@@ -10,6 +10,11 @@\n function tspoll_fetch_remote_data_callback() {\n     check_ajax_referer( 'tspoll_nonce', 'nonce' );\n-    $url = $_POST['url'];\n+    $url = esc_url_raw( $_POST['url'] );\n+    if ( ! wp_http_validate_url( $url ) ) {\n+        wp_send_json_error( 'Invalid URL' );\n+    }\n     $response = wp_remote_get( $url );","An attacker with Editor-level authentication must first obtain a valid AJAX nonce from the TS Poll admin dashboard (likely via a localized script variable like 'window.tspoll_admin_obj.nonce'). Then, the attacker sends a POST request to '\u002Fwp-admin\u002Fadmin-ajax.php' with the action set to 'tspoll_fetch_remote_data' (or a similar remote-fetching action) and a 'url' parameter targeting an internal resource, such as 'http:\u002F\u002F169.254.169.254\u002Flatest\u002Fmeta-data\u002F'. The server performs the request and returns the resulting content in the AJAX response.","gemini-3-flash-preview","2026-05-04 23:27:21","2026-05-04 23:27:37",{"type":34,"vulnerable_version":9,"fixed_version":9,"vulnerable_browse":9,"vulnerable_zip":9,"fixed_browse":9,"fixed_zip":9,"all_tags":35},"plugin","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fpoll-wp\u002Ftags"]