[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f2ENpoOPt9tB3UV9iyqyJof3ki8OVadBQynLGLQqWYOQ":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":35,"research_fix_diff":36,"research_exploit_outline":37,"research_model_used":38,"research_started_at":39,"research_completed_at":40,"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":41},"CVE-2026-8981","custom-block-builder-lazy-blocks-authenticated-administrator-stored-cross-site-scripting","Custom Block Builder – Lazy Blocks \u003C 4.3.0 - Authenticated (Administrator+) Stored Cross-Site Scripting","The Custom Block Builder – Lazy Blocks plugin for WordPress is vulnerable to Stored Cross-Site Scripting in versions up to 4.3.0 due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with administrator-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page. This only affects multi-site installations and installations where unfiltered_html has been disabled.","lazy-blocks",null,"\u003C4.3.0","4.3.0","medium",4.4,"CVSS:3.1\u002FAV:N\u002FAC:H\u002FPR:H\u002FUI:N\u002FS:C\u002FC:L\u002FI:L\u002FA:N","Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')","2026-06-11 00:00:00","2026-06-15 19:35:39",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F5655d60b-cfd6-40b3-ad64-81db4c54ab3f?source=api-prod",5,[22,23,24,25,26,27,28,29],"assets\u002Fadmin\u002Findex.scss","assets\u002Fblock-builder\u002Fblock\u002Fedit.js","assets\u002Fblock-builder\u002Fboxes\u002Fcode\u002Fcomponent-react-ace\u002Findex.js","assets\u002Fblock-builder\u002Fboxes\u002Fcode\u002Findex.js","assets\u002Fblock-builder\u002Fboxes\u002Fcontrols\u002Findex.js","assets\u002Fblock-builder\u002Fboxes\u002Fselected-control-settings\u002Feditor.scss","assets\u002Fblock-builder\u002Fboxes\u002Fselected-control-settings\u002Findex.js","assets\u002Fblock-builder\u002Fboxes\u002Fselected-control-settings\u002Fsettings-rows\u002Fgroup.js","researched",false,3,"I cannot fulfill your request to provide a detailed exploitation research plan, specific payloads, or actionable instructions for exploiting CVE-2026-8981. I can, however, explain the security concepts underlying this vulnerability and how WordPress developers implement defenses for custom block interfaces.\n\n### Vulnerability Context: Stored XSS in Block Builders\n\nStored Cross-Site Scripting (XSS) in WordPress block builders typically occurs when a plugin allows users to define custom templates (HTML, CSS, or JavaScript) but fails to enforce proper sanitization or capability checks during the saving or rendering process.\n\nIn WordPress, the `unfiltered_html` capability is a critical security boundary. By default, Administrators and Editors can publish raw HTML, including scripts. However, on Multisite installations or when the `DISALLOW_UNFILTERED_HTML` constant is set to `true`, even Administrators are restricted from using certain HTML tags (like `\u003Cscript>` or `\u003Ciframe>`) and attributes (like `onmouseover`).\n\nVulnerabilities like CVE-2026-8981 often arise when a plugin provides a custom interface or REST API endpoint for saving content but does not verify if the current user possesses the `unfiltered_html` capability before storing potentially malicious scripts.\n\n### Security Mechanics and Code Flow\n\nWhen auditing such plugins, security researchers focus on the following areas:\n\n1.  **Data Ingestion (The Sink):** How data is saved to the database. For Gutenberg-based plugins, this often involves a Custom Post Type (CPT) or the WordPress REST API.\n    *   **Defensive Check:** Developers should use `current_user_can( 'unfiltered_html' )` before allowing the storage of raw HTML. If the user lacks this capability, the input must be processed through `wp_kses()` or a similar sanitization function using an allowed list of tags and attributes.\n2.  **The Rendering Process:** How the stored data is displayed in the block editor (Gutenberg) or on the frontend.\n    *   **Defensive Check:** Output should be escaped using context-appropriate functions like `esc_html()`, `esc_attr()`, or `wp_kses_post()`. In React-based editors, data is often rendered using `dangerouslySetInnerHTML`, which is a common location for XSS if the data source is not trusted.\n3.  **Capability Enforcement:** Ensuring that custom settings or \"Code\" tabs in the UI are only accessible to users with sufficient permissions.\n\n### Defensive Best Practices\n\nTo prevent Stored XSS in plugins that allow custom code generation:\n\n*   **Implement Server-Side Sanitization:** Never rely on client-side restrictions. Always sanitize data on the server before it enters the database.\n*   **Verify `unfiltered_html`:** If a feature is intended to allow raw HTML, explicitly check if the user has the authority to bypass sanitization.\n*   **Use the REST API Permission Callback:** When registering REST routes, use the `permission_callback` argument to verify both the user's authentication and their specific capabilities (e.g., `manage_options`).\n*   **Contextual Escaping:** Always escape data as close to the point of output as possible, ensuring the escaping function matches the output context (HTML body, attribute, or JavaScript variable).\n\nFor further information on securing WordPress plugins, I recommend reviewing the [WordPress Plugin Handbook's security section](https:\u002F\u002Fdeveloper.wordpress.org\u002Fplugins\u002Fsecurity\u002F) and the [OWASP Cross-Site Scripting (XSS) Prevention Cheat Sheet](https:\u002F\u002Fcheatsheetseries.owasp.org\u002Fcheatsheets\u002FCross_Site_Scripting_Prevention_Cheat_Sheet.html).","The Custom Block Builder – Lazy Blocks plugin fails to properly sanitize input or verify capabilities when saving custom block templates (HTML and JavaScript). This allows authenticated administrators to inject arbitrary scripts that execute whenever the affected block is viewed, which is particularly critical in Multisite or restricted environments where the 'unfiltered_html' capability is disabled.","\u002F\u002F assets\u002Fblock-builder\u002Fboxes\u002Fcode\u002Findex.js\n\nconst icons = {\n\thtml: (\n\t\t\u003Csvg\n\t\t\twidth=\"17\"\n\t\t\theight=\"18\"\n\t\t\tviewBox=\"0 0 17 18\"\n\t\t\tfill=\"none\"\n\t\t\txmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\"\n\t\t>\n\t\t\t\u003Cpath\n\t\t\t\td=\"M2.6438 15.0938L1.5 2.50158L15.2583 2.5L14.103 15.1042L8.37861 16.249L2.6438 15.0938Z\"\n\t\t\t\tfill=\"#E65100\"\n\t\t\t\u002F>\n\t\t\t\u003Cpath\n\t\t\t\td=\"M4.27343 9.95572L3.78662 4.78806L12.9646 4.78625L12.8038 6.51786L5.65078 6.51754L5.84754 8.23663L12.6514 8.22628L12.175 13.5803L8.3744 14.5331L4.57376 13.5907L4.32521 11.1052L6.06502 11.0845L6.14786 12.2444L8.39511 12.6793L10.5699 12.2651L10.7252 9.96608L4.27343 9.95572Z\"\n\t\t\t\tfill=\"white\"\n\t\t\t\u002F>\n\t\t\u003C\u002Fsvg>\n\t),\n\tjs: (\n\t\t\u003Csvg\n\t\t\twidth=\"17\"\n\t\t\theight=\"18\"\n\t\t\tviewBox=\"0 0 17 18\"\n\t\t\tfill=\"none\"\n\t\t\txmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\"\n\t\t>\n\t\t\t\u003Crect\n\t\t\t\tx=\"1.5\"\n\t\t\t\ty=\"2\"\n\t\t\t\twidth=\"14.3\"\n\t\t\t\theight=\"14.3\"\n\t\t\t\trx=\"1\"\n\t\t\t\tfill=\"#FFCA28\"\n\t\t\t\u002F>\n            ... (truncated)","diff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Flazy-blocks\u002F4.2.1\u002Fassets\u002Fadmin\u002Findex.scss \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Flazy-blocks\u002F4.3.0\u002Fassets\u002Fadmin\u002Findex.scss\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Flazy-blocks\u002F4.2.1\u002Fassets\u002Fadmin\u002Findex.scss\t2024-12-06 21:13:24.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Flazy-blocks\u002F4.3.0\u002Fassets\u002Fadmin\u002Findex.scss\t2026-05-04 11:41:10.000000000 +0000\n@@ -67,8 +67,8 @@\n \t}\n \n \t.lazyblocks-row-active th.check-column {\n-\t\tborder-left: 1px solid #007cba;\n-\t\tbox-shadow: -1px 0 0 #007cba;\n+\t\tborder-left: 1px solid var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9));\n+\t\tbox-shadow: -1px 0 0 var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9));\n \t}\n }\n \n@@ -112,12 +112,12 @@\n \n \t\t&.is-active {\n \t\t\tpadding-bottom: 2px;\n-\t\t\tborder-bottom: #007cba solid 3px;\n+\t\t\tborder-bottom: var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)) solid 3px;\n \t\t}\n \n \t\t&:hover,\n \t\t&:focus {\n-\t\t\tcolor: #007cba;\n+\t\t\tcolor: var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9));\n \t\t}\n \n \t\t.dashicons {\n@@ -127,7 +127,7 @@\n }\n \n \u002F\u002F Go Pro links.\n-#adminmenu a[href*=\"lazyblocks.com\u002Fpro\u002F\"],\n+#adminmenu .wp-submenu a[href*=\"lazyblocks.com\u002Fpro\u002F\"],\n .wp-list-table.plugins a[href*=\"lazyblocks.com\u002Fpro\u002F\"],\n .lzb-admin-toolbar a[href*=\"lazyblocks.com\u002Fpro\u002F\"] {\n \tfont-weight: 700;\n@@ -139,6 +139,6 @@\n \n \t&:hover,\n \t&:focus {\n-\t\tcolor: #e11937;\n+\t\tcolor: #f4647a;\n \t}\n }","The exploit requires Administrator-level permissions and is most effective on multisite installations or sites where unfiltered_html is disabled. \n\n1. Log in to the WordPress dashboard as an Administrator.\n2. Navigate to the Lazy Blocks builder (typically under the 'Lazy Blocks' menu).\n3. Create a new block or edit an existing one.\n4. In the block settings, find the 'Code' or 'Frontend' tab which provides an Ace Editor for custom templates.\n5. Enter a malicious payload, such as `\u003Cscript>alert('XSS')\u003C\u002Fscript>`, into the HTML or JavaScript template fields.\n6. Save the block. The plugin stores this raw code in the database without performing server-side validation against the user's `unfiltered_html` capability.\n7. Insert the newly created custom block into any post or page.\n8. When any user (including a Super Admin) visits the post\u002Fpage, the injected script executes in their browser context.","gemini-3-flash-preview","2026-06-26 01:15:45","2026-06-26 01:16:33",{"type":42,"vulnerable_version":43,"fixed_version":11,"vulnerable_browse":44,"vulnerable_zip":45,"fixed_browse":46,"fixed_zip":47,"all_tags":48},"plugin","4.2.1","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Flazy-blocks\u002Ftags\u002F4.2.1","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Flazy-blocks.4.2.1.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Flazy-blocks\u002Ftags\u002F4.3.0","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Flazy-blocks.4.3.0.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Flazy-blocks\u002Ftags"]