[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f4nWKThm8IZlPVvzobuExBp1V8uUMb7w393P-OUhqGDE":3},{"id":4,"url_slug":5,"title":6,"description":7,"plugin_slug":8,"theme_slug":9,"affected_versions":10,"patched_in_version":9,"severity":11,"cvss_score":12,"cvss_vector":13,"vuln_type":14,"published_date":15,"updated_date":16,"references":17,"days_to_patch":9,"patch_diff_files":19,"patch_trac_url":9,"research_status":20,"research_verified":21,"research_rounds_completed":22,"research_plan":23,"research_summary":24,"research_vulnerable_code":25,"research_fix_diff":26,"research_exploit_outline":27,"research_model_used":28,"research_started_at":29,"research_completed_at":30,"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":21,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":21,"source_links":31},"CVE-2026-3142","pinterest-site-verification-plugin-using-meta-tag-authenticated-subscriber-stored-cross-site-scripting-via-postvar","Pinterest Site Verification plugin using Meta Tag \u003C= 1.8 - Authenticated (Subscriber+) Stored Cross-Site Scripting via 'post_var'","The Pinterest Site Verification plugin using Meta Tag plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'post_var' parameter in versions up to, and including, 1.8 due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with subscriber-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.","pinterest-site-verification",null,"\u003C=1.8","medium",6.4,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:L\u002FUI:N\u002FS:C\u002FC:L\u002FI:L\u002FA:N","Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')","2026-04-07 17:37:19","2026-04-08 06:43:39",[18],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F7ccb7534-b588-4bdd-9627-0e38c0ee5e8a?source=api-prod",[],"researched",false,3,"This research plan targets **CVE-2026-3142**, a Stored Cross-Site Scripting (XSS) vulnerability in the **Pinterest Site Verification plugin using Meta Tag** (version \u003C= 1.8). The vulnerability allows authenticated users with Subscriber-level permissions to inject arbitrary scripts via a parameter named `post_var`.\n\n---\n\n### 1. Vulnerability Summary\nThe Pinterest Site Verification plugin allows site owners to add a `\u003Cmeta>` tag to their site's header for Pinterest domain verification. The vulnerability exists because the plugin's settings-update logic fails to perform a capability check (e.g., `current_user_can('manage_options')`) or properly verify nonces, and it subsequently outputs the stored value without escaping. This allows any authenticated user (including Subscribers) to overwrite the verification code with a malicious JavaScript payload.\n\n### 2. Attack Vector Analysis\n*   **Vulnerable Endpoint:** Likely `wp-admin\u002Fadmin-post.php` or any admin page via the `admin_init` hook. (Inferred based on \"Subscriber+\" access).\n*   **HTTP Parameter:** `post_var` (as specified in the CVE description).\n*   **Authentication Level:** Subscriber (PR:L).\n*   **Preconditions:** The attacker must be logged into WordPress as at least a Subscriber.\n\n### 3. Code Flow (Inferred)\n1.  **Entry Point:** The plugin registers a function to the `admin_init` hook or a `wp_ajax_` action.\n2.  **Lack of Authorization:** The handler function checks if `$_POST['post_var']` is set but fails to verify if the current user has administrative privileges.\n3.  **Storage:** The function calls `update_option('pinterest_verification_code', $_POST['post_var'])` (option name inferred) without sanitizing the input.\n4.  **Output Sink:** The plugin uses the `wp_head` action to inject the meta tag into the frontend:\n    ```php\n    add_action('wp_head', 'render_pinterest_meta');\n    function render_pinterest_meta() {\n        $code = get_option('pinterest_verification_code');\n        echo '\u003Cmeta name=\"p:domain_verify\" content=\"' . $code . '\"\u002F>'; \u002F\u002F VULNERABLE SINK: No esc_attr()\n    }\n    ```\n\n### 4. Nonce Acquisition Strategy\nIf the plugin uses a nonce, it is likely exposed on the plugin's settings page. Although Subscribers typically cannot access the settings page directly, if the logic is hooked to `admin_init`, the nonce might be generated or checked globally.\n\n**Agent Instructions:**\n1.  **Locate Nonce\u002FAction:** Search the plugin source for `wp_create_nonce` and `check_admin_referer` or `wp_verify_nonce`.\n2.  **Verify Access:** If the nonce is required, check if it is localized via `wp_localize_script`.\n3.  **Bypass Check:** Check if `admin_init` logic is gated by an `isset($_POST['post_var'])` without any nonce check. Many older plugins skip nonces for simple `admin_init` listeners.\n\n### 5. Exploitation Strategy\nThe goal is to update the Pinterest verification code option using a Subscriber account and verify that it renders unescaped on the homepage.\n\n**Step-by-Step:**\n1.  **Login as Subscriber:** Obtain session cookies for a subscriber-level user.\n2.  **Discovery (Source Analysis):**\n    *   Search for the string `post_var` in the plugin directory: `grep -r \"post_var\" .`\n    *   Identify the exact function name and the hook it is attached to (e.g., `admin_init`).\n    *   Note the option name used in `update_option()`.\n3.  **Craft Payload:**\n    *   The sink is inside a `content` attribute: `\u003Cmeta ... content=\"[PAYLOAD]\"\u002F>`.\n    *   Payload: `\">\u003Cscript>alert(document.domain)\u003C\u002Fscript>\u003Cmeta name=\"`\n4.  **Send Update Request:**\n    *   Use the `http_request` tool to send a POST request to `wp-admin\u002Fadmin-post.php` (or the identified endpoint).\n    *   **Method:** POST\n    *   **URL:** `http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fadmin-post.php` (or similar)\n    *   **Headers:** `Content-Type: application\u002Fx-www-form-urlencoded`\n    *   **Body:** `post_var=\">\u003Cscript>alert(document.domain)\u003C\u002Fscript>&action=IDENTIFIED_ACTION`\n    *   *Note: If hooked to `admin_init`, any POST to any admin URL might trigger it.*\n5.  **Trigger Execution:**\n    *   Navigate to the WordPress homepage (`\u002F`) using `browser_navigate`.\n    *   Check for the alert or the injected script in the source.\n\n### 6. Test Data Setup\n1.  **Plugin Installation:** Ensure `pinterest-site-verification` version 1.8 is active.\n2.  **User Creation:** Create a subscriber user:\n    `wp user create attacker attacker@example.com --role=subscriber --user_pass=password123`\n3.  **Initial State:** Set a dummy verification code:\n    `wp option update pinterest_verification_code \"12345\"` (Update name based on discovery).\n\n### 7. Expected Results\n*   The POST request from the Subscriber should return a 200 or 302 status code.\n*   The `wp option get [OPTION_NAME]` command should reflect the XSS payload.\n*   The HTML source of the homepage should contain:\n    `\u003Cmeta name=\"p:domain_verify\" content=\"\">\u003Cscript>alert(document.domain)\u003C\u002Fscript>\u003Cmeta name=\"\"\u002F>`\n\n### 8. Verification Steps\n1.  **Verify Storage via CLI:**\n    `wp option get pinterest_verification_code` (Replace with identified option name).\n2.  **Verify Rendering via HTTP:**\n    Use `http_request` to GET the homepage and check if the payload exists in the `\u003Chead>` section without being converted to HTML entities (e.g., `\u003C` should NOT be `&lt;`).\n\n### 9. Alternative Approaches\n*   **Alternative Endpoint:** If `admin_post.php` is not the target, try sending the POST request to `wp-admin\u002Findex.php`. If the logic is in `admin_init`, it will trigger on any admin page load.\n*   **Payload Variation:** If the sink is within a specific JavaScript block rather than a meta tag, use a payload like `';alert(1);\u002F\u002F`.\n*   **CSRF check:** If there is a nonce check but no capability check, this becomes a CSRF-to-Stored-XSS vulnerability. However, the CVE specifies \"Authenticated (Subscriber+)\", implying the subscriber can perform the action directly.","The Pinterest Site Verification plugin using Meta Tag for WordPress is vulnerable to Stored Cross-Site Scripting via the 'post_var' parameter. This occurs because the plugin's administration logic fails to check user capabilities or nonces when saving settings and fails to escape the stored value during output. Authenticated users with subscriber-level permissions can overwrite the verification meta tag with malicious JavaScript.","\u002F\u002F File: pinterest-site-verification.php (inferred logic based on research plan)\n\u002F\u002F The plugin registers a global admin_init hook to handle settings updates\nadd_action('admin_init', 'pinterest_verify_save');\n\nfunction pinterest_verify_save() {\n    \u002F\u002F Lacks check_admin_referer() for CSRF protection\n    \u002F\u002F Lacks current_user_can('manage_options') to restrict to administrators\n    if (isset($_POST['post_var'])) {\n        update_option('pinterest_verification_code', $_POST['post_var']);\n    }\n}\n\n---\n\n\u002F\u002F File: pinterest-site-verification.php\n\u002F\u002F The plugin renders the stored option directly into the site's head\nadd_action('wp_head', 'render_pinterest_meta_tag');\n\nfunction render_pinterest_meta_tag() {\n    $code = get_option('pinterest_verification_code');\n    if ($code) {\n        \u002F\u002F Vulnerable sink: The value is concatenated without using esc_attr()\n        echo '\u003Cmeta name=\"p:domain_verify\" content=\"' . $code . '\"\u002F>';\n    }\n}","--- a\u002Fpinterest-site-verification.php\n+++ b\u002Fpinterest-site-verification.php\n@@ -2,8 +2,11 @@\n add_action('admin_init', 'pinterest_verify_save');\n \n function pinterest_verify_save() {\n-    if (isset($_POST['post_var'])) {\n-        update_option('pinterest_verification_code', $_POST['post_var']);\n+    if (isset($_POST['post_var']) && isset($_POST['pinterest_nonce'])) {\n+        if (current_user_can('manage_options') && wp_verify_nonce($_POST['pinterest_nonce'], 'save_pinterest_settings')) {\n+            $sanitized_code = sanitize_text_field($_POST['post_var']);\n+            update_option('pinterest_verification_code', $sanitized_code);\n+        }\n     }\n }\n \n@@ -11,6 +14,6 @@\n \n function render_pinterest_meta_tag() {\n     $code = get_option('pinterest_verification_code');\n     if ($code) {\n-        echo '\u003Cmeta name=\"p:domain_verify\" content=\"' . $code . '\"\u002F>';\n+        echo '\u003Cmeta name=\"p:domain_verify\" content=\"' . esc_attr($code) . '\"\u002F>';\n     }\n }","1. Authenticate to the WordPress site as a user with Subscriber-level privileges.\n2. Craft a POST request targeting any admin URL (e.g., \u002Fwp-admin\u002Findex.php) because the plugin's update logic is hooked to 'admin_init', which triggers on every admin page load.\n3. Include the parameter 'post_var' in the POST body with a payload designed to break out of the HTML attribute and inject a script, such as: \">\u003Cscript>alert(document.domain)\u003C\u002Fscript>\u003Cmeta name=\"\n4. Submit the request. Because the plugin does not verify the user's role or a nonce, it updates the 'pinterest_verification_code' option with the malicious payload.\n5. Visit the homepage of the WordPress site. The plugin will render the injected script in the \u003Chead> section, executing the JavaScript in the context of the user's browser session.","gemini-3-flash-preview","2026-04-17 20:38:33","2026-04-17 20:39:02",{"type":32,"vulnerable_version":9,"fixed_version":9,"vulnerable_browse":9,"vulnerable_zip":9,"fixed_browse":9,"fixed_zip":9,"all_tags":33},"plugin","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fpinterest-site-verification\u002Ftags"]