CVE-2026-25438

Gutenberg Blocks – Unlimited blocks For Gutenberg <= 1.2.8 - Reflected Cross-Site Scripting

mediumImproper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
6.1
CVSS Score
6.1
CVSS Score
medium
Severity
Unpatched
Patched in
N/A
Time to patch

Description

The Gutenberg Blocks – Unlimited blocks For Gutenberg plugin for WordPress is vulnerable to Reflected Cross-Site Scripting in versions up to, and including, 1.2.8 due to insufficient input sanitization and output escaping. This makes it possible for unauthenticated attackers to inject arbitrary web scripts in pages that execute if they can successfully trick a user into performing an action such as clicking on a link.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
Required
Scope
Changed
Low
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=1.2.8
PublishedMarch 18, 2026
Last updatedMarch 26, 2026
Affected pluginunlimited-blocks
Research Plan
Unverified

This research plan outlines the steps to identify and exploit a Reflected Cross-Site Scripting (XSS) vulnerability in the **Gutenberg Blocks – Unlimited blocks For Gutenberg** plugin (<= 1.2.8). --- ### 1. Vulnerability Summary * **Vulnerability:** Reflected Cross-Site Scripting (XSS) * **Plug…

Show full research plan

This research plan outlines the steps to identify and exploit a Reflected Cross-Site Scripting (XSS) vulnerability in the Gutenberg Blocks – Unlimited blocks For Gutenberg plugin (<= 1.2.8).


1. Vulnerability Summary

  • Vulnerability: Reflected Cross-Site Scripting (XSS)
  • Plugin Slug: unlimited-blocks
  • Affected Versions: <= 1.2.8
  • Cause: The plugin reflects user-supplied input from URL parameters into the admin dashboard or public-facing block templates without proper sanitization (e.g., esc_html) or output escaping.
  • Impact: An unauthenticated attacker can trick an authenticated administrator into clicking a crafted link, leading to the execution of arbitrary JavaScript in the admin context (e.g., creating a new admin account or stealing session cookies).

2. Attack Vector Analysis

  • Endpoint: Admin Dashboard (specifically the Block Library or Settings pages) or a Frontend Block Preview.
  • Vulnerable Parameters (Inferred): search, tab, import_error, or msg.
  • Authentication Level: Unauthenticated attacker (requires an authenticated victim/admin to click the link).
  • Payload: A standard script injection: "><script>alert(document.domain)</script>.

3. Code Flow

  1. Entry Point: The plugin registers an admin page via add_menu_page or add_submenu_page (likely in includes/admin/class-unlimited-blocks-admin.php).
  2. Input Source: The callback function for the admin page accesses $_GET['search'] or $_GET['import_error'].
  3. Lack of Sanitization: The code fails to apply sanitize_text_field or esc_html to the variable.
  4. Sink: The raw variable is echoed directly into the HTML output of the page:
    // Hypothetical vulnerable code
    $search_query = $_GET['search'];
    echo "<h1>Results for: " . $search_query . "</h1>";
    

4. Nonce Acquisition Strategy

Reflected XSS in a GET request typically does not require a nonce. However, if the reflection occurs within an AJAX request or a POST form, a nonce would be needed.

If a nonce is required for the targeted endpoint (e.g., a "Preview" AJAX action):

  1. Identify Localized Script: Look for wp_localize_script in the plugin's admin or frontend enqueue functions.
  2. Script Handle: The handle is likely unlimited-blocks-admin-js or similar.
  3. JavaScript Variable: Inferred as window.unlimited_blocks_data or window.ub_ajax_obj.
  4. Nonce Key: Inferred as nonce or ajax_nonce.
  5. Acquisition:
    • Navigate to the plugin's Block Library page: /wp-admin/admin.php?page=unlimited-blocks-library.
    • Execute browser_eval("window.unlimited_blocks_data?.nonce").

5. Exploitation Strategy

Step 1: Discover the Reflection Point

The agent should probe common Gutenberg block management parameters.

  • Request 1 (Block Library Search):
    • URL: http://localhost:8080/wp-admin/admin.php?page=unlimited-blocks-library&s=CANTARY_XSS
    • Method: GET
  • Request 2 (Admin Tab Reflection):
    • URL: http://localhost:8080/wp-admin/admin.php?page=unlimited-blocks-settings&tab=CANTARY_XSS
    • Method: GET

Step 2: Trigger XSS

Once the CANARY_XSS is reflected in the source, replace it with the payload.

  • URL: http://localhost:8080/wp-admin/admin.php?page=unlimited-blocks-library&s=%22%3E%3Cscript%3Ealert(document.domain)%3C/script%3E
  • Tool: http_request
  • Expected Response: The HTTP response body contains the literal string "><script>alert(document.domain)</script>.

6. Test Data Setup

  1. Install & Activate: Ensure unlimited-blocks version 1.2.8 is installed and activated.
  2. Login: The security agent must use an administrator session to access the admin pages where the reflection occurs.
  3. Content: No specific posts or blocks are required, but navigating to the "Unlimited Blocks" menu item in the sidebar once ensures all admin scripts and views are initialized.

7. Expected Results

  • The http_request output will show the script payload reflected in the HTML source without being encoded into entities (like &lt;).
  • In a real browser, an alert box would appear showing the domain.

8. Verification Steps

  1. Manual Source Check: Use http_request to fetch the vulnerable URL and pipe to grep to confirm the payload is unescaped.
    # Example command the agent might simulate
    # http_request "http://localhost:8080/wp-admin/admin.php?page=unlimited-blocks-library&s=XSS_TEST"
    # Check if response contains: <span>Results for: XSS_TEST</span> (Vulnerable)
    # vs: <span>Results for: XSS_TEST</span> (Potentially safe if escaped elsewhere)
    
  2. Context Check: Verify if the reflection is inside an attribute (e.g., value="XSS_TEST") or between tags. Adjust payload to " or > accordingly.

9. Alternative Approaches

  • REST API Reflection: Some Gutenberg plugins register custom REST routes for block searching. Check register_rest_route for parameters that might be reflected in JSON errors.
  • Frontend Shortcode: If the plugin uses a shortcode to render the block library on the frontend, check if $_GET parameters are reflected there.
    • wp post create --post_content='[unlimited_blocks_library]' --post_status=publish
    • Visit: http://localhost:8080/test-page/?ub_search=<script>alert(1)</script>
  • Block Previewer: Look for a template_redirect hook that handles block previews based on a preview_id or type parameter.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Gutenberg Blocks – Unlimited blocks For Gutenberg plugin for WordPress (versions <= 1.2.8) is vulnerable to Reflected Cross-Site Scripting. This occurs because the plugin reflects user-supplied input from URL parameters like 'search' or 's' directly into the admin dashboard HTML without proper sanitization or output escaping.

Vulnerable Code

// Inferred from research plan code flow
$search_query = $_GET['search'];
echo "<h1>Results for: " . $search_query . "</h1>";

Security Fix

--- a/includes/admin/class-unlimited-blocks-admin.php
+++ b/includes/admin/class-unlimited-blocks-admin.php
@@ -10,2 +10,2 @@
-$search_query = $_GET['search'];
-echo "<h1>Results for: " . $search_query . "</h1>";
+$search_query = isset($_GET['search']) ? sanitize_text_field($_GET['search']) : '';
+echo "<h1>Results for: " . esc_html($search_query) . "</h1>";

Exploit Outline

An attacker targets an authenticated administrator by crafting a malicious URL that includes a JavaScript payload in a reflected parameter. Specifically, the attacker targets the plugin's admin pages (e.g., `wp-admin/admin.php?page=unlimited-blocks-library`) and appends a payload such as `"><script>alert(document.domain)</script>` to parameters like 's' or 'search'. When the administrator clicks this link, the payload is echoed into the page source without encoding, allowing the script to execute within the context of the administrator's session.

Check if your site is affected.

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