CVE-2026-32403

Toocheke Companion <= 1.194 - Authenticated (Contributor+) Stored Cross-Site Scripting

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

Description

The Toocheke Companion plugin for WordPress is vulnerable to Stored Cross-Site Scripting in versions up to, and including, 1.194 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<=1.194
PublishedFebruary 21, 2026
Last updatedApril 15, 2026
Affected plugintoocheke-companion

What Changed in the Fix

Changes introduced in v1.195

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan focuses on exploiting a Stored Cross-Site Scripting (XSS) vulnerability in the **Toocheke Companion** plugin (version <= 1.194). The vulnerability allows users with **Contributor-level** permissions and above to inject malicious scripts via shortcode attributes that are rendered w…

Show full research plan

This research plan focuses on exploiting a Stored Cross-Site Scripting (XSS) vulnerability in the Toocheke Companion plugin (version <= 1.194). The vulnerability allows users with Contributor-level permissions and above to inject malicious scripts via shortcode attributes that are rendered without proper escaping.

1. Vulnerability Summary

  • Vulnerability: Stored Cross-Site Scripting (XSS)
  • Plugin: Toocheke Companion
  • Affected Versions: <= 1.194
  • Sink: Shortcode rendering functions (specifically archive-related shortcodes).
  • Cause: The plugin fails to sanitize or escape the term attribute (and potentially others like sid or link_to) when displaying the shortcode's output on the frontend.
  • Permission: Authenticated (Contributor+)

2. Attack Vector Analysis

  • Endpoint: WordPress Post Editor / Frontend Page Rendering
  • Vulnerable Component: Shortcode handlers. Based on the readme.txt, the following shortcodes are prime candidates for the term attribute injection:
    • [toocheke-collection-archive term="..."]
    • [toocheke-chapter-archive term="..."]
    • [toocheke-tag-archive term="..."]
    • [toocheke-location-archive term="..."]
    • [toocheke-character-archive term="..."]
  • Payload Parameter: term attribute within the shortcode.
  • Preconditions: The attacker must have a Contributor account to create a post and include the shortcode.

3. Code Flow

  1. Input: A Contributor creates a post containing the shortcode: [toocheke-collection-archive term='"><script>alert(document.domain)</script>'].
  2. Storage: WordPress stores this string in the post_content table.
  3. Registration: The plugin registers shortcode handlers (likely in an init hook, though truncated in the source provided).
  4. Processing: When the post is viewed, WordPress parses the shortcode and calls the plugin's handler function (e.g., toocheke_collection_archive_shortcode).
  5. Sink: The handler retrieves the term attribute from the $atts array and echoes it back into the HTML (likely inside a heading or a container div) without using esc_html() or esc_attr().

4. Nonce Acquisition Strategy

Shortcode-based XSS does not require a nonce for execution. The payload is stored as part of the post content through the standard WordPress post-saving mechanism (which handles its own nonces). Once saved, the script executes whenever any user (including an Administrator) views the post.

5. Exploitation Strategy

  1. Login as Contributor: Use the http_request tool to authenticate with contributor credentials.
  2. Create Malicious Post: Submit a request to wp-admin/post-new.php or use the REST API/AJAX autosave to create a post containing the payload.
  3. Inject Payload: Use the [toocheke-collection-archive] shortcode with an attribute breakout.
    • Payload: [toocheke-collection-archive term='"><img src=x onerror=alert(window.origin)>']
  4. Trigger Execution: Navigate to the newly created post's permalink using browser_navigate.
  5. Capture Output: Verify the alert or presence of the unescaped HTML in the page source.

6. Test Data Setup

  1. User Creation: Create a user with the contributor role.
    wp user create attacker attacker@example.com --role=contributor --user_pass=password123
    
  2. Plugin Activation: Ensure Toocheke Companion is active.
    wp plugin activate toocheke-companion
    

7. Expected Results

  • The shortcode handler will render the HTML. If vulnerable, the output will look like:
    <div class="toocheke-archive-title">Archive: "><img src=x onerror=alert(window.origin)></div>
  • The browser will execute the onerror event, triggering the alert.

8. Verification Steps

  1. Check Page Source: After navigation, check if the string onerror=alert exists in the rendered HTML without being encoded as &lt; or &quot;.
  2. Admin Context: Navigate to the post as an Administrator to confirm that the script executes in a high-privileged context (this is the primary impact).
  3. Database Check:
    wp db query "SELECT post_content FROM wp_posts WHERE post_title = 'XSS Test'"
    

9. Alternative Approaches

If the term attribute is sanitized, try these other attributes/shortcodes identified in readme.txt:

  • Link Attribute: [toocheke-all-series link_to='"><script>alert(1)</script>']
  • Order Attribute: [toocheke-all-series comics_order='"><script>alert(1)</script>']
  • Series ID Attribute: [toocheke-all-chapters sid='"><script>alert(1)</script>']

If the Block Editor is used, the payload would be stored in the Gutenberg block comment:

<!-- wp:toocheke/collection-archive {"term":"\u0022\u003e\u003cimg src=x onerror=alert(1)\u003e"} /-->

The exploitation logic remains the same as the rendering callback for the block is usually shared with the shortcode handler.

Check if your site is affected.

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