CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-47760

CVE-2026-47760: Cross-Site Scripting (XSS) via SVG Namespace Sanitizer Bypass in TinyMCE

Alon Barad
Alon Barad
Software Engineer

Jun 6, 2026·7 min read·11 visits

Executive Summary (TL;DR)

A high-severity Cross-Site Scripting (XSS) vulnerability (CVSS 8.7) in TinyMCE (versions >= 6.8.0, < 7.1.0) allows attackers to bypass HTML sanitization using nested SVGs and execute arbitrary JavaScript code inside a victim's browser.

TinyMCE versions 6.8.0 through 7.0.1 contain a high-severity Cross-Site Scripting (XSS) vulnerability. The flaw exists in the custom HTML parser and sanitizer module, which incorrectly manages SVG namespace scopes when parsing nested elements. A low-privileged or unauthenticated attacker can submit a crafted HTML payload containing nested SVG structures to bypass sanitization filters, leading to arbitrary JavaScript execution in the context of the victim's browser session.

Vulnerability Overview

TinyMCE is an industry-standard, open-source rich text editor widely integrated into web applications, content management systems, and enterprise portals. In version 6.8.0, TinyMCE introduced native support for parsing and validating Scalable Vector Graphics (SVG) elements to allow authors to insert rich graphic content directly within the editing panel. To ensure security, TinyMCE processes all inputted HTML through a custom, string-based sanitization pipeline prior to rendering.

This pipeline is managed by custom classes within the editor's architecture, primarily the html/Parser.ts and html/Sanitizer.ts modules. Rather than leveraging the host browser's native DOM parser, which can cause layout shifts and strip structural formatting, TinyMCE tokenizes and parses the input manually against a configured schema. This design creates a substantial attack surface, as any parsing mismatch between TinyMCE's internal serializer and the browser's native rendering engine can be exploited.

The vulnerability is classified under CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting'). It affects versions 6.8.0 through 7.0.1 (encompassing both the 6.8.x and 7.0.x release branches). By introducing specific nested SVG elements, an attacker can desynchronize the sanitizer's internal namespace tracking state from the parsing rules applied by the browser's HTML5 engine.

Root Cause Analysis

To understand the root cause, it is necessary to examine how web browsers handle namespaces under the HTML5 parsing specification. When a browser's HTML parser encounters an <svg> tag, it transitions from the default HTML namespace (http://www.w3.org/1999/xhtml) to the SVG namespace (http://www.w3.org/2000/svg). Elements within this scope are parsed as "foreign content" with distinct parsing behaviors.

The HTML5 specification defines standard integration points where the parser switches back to the HTML namespace. Inside an SVG, elements such as <desc>, <title>, and <metadata> act as HTML integration points. Any children of these tags transition back to the default HTML namespace. However, if a standard HTML element is placed directly inside an SVG scope without being wrapped in an integration point, the browser's parser immediately terminates the active SVG scope, pops the SVG namespace off its stack, and processes the element under HTML rules.

TinyMCE's custom sanitizer fails to implement this complex, stateful namespace stack. Instead, the parser tracked SVG namespace transitions using simplified state variables (such as a flat boolean flag or an incorrectly updated nesting counter). When the sanitizer encounters nested SVG elements combined with HTML integration points (such as <desc>), its internal state tracker becomes desynchronized from the browser's parser.

If the sanitizer registers a nested closing </svg> tag, it transitions its parsing state back to the HTML namespace, assuming the SVG block has terminated. However, the browser's parser remains inside the parent SVG namespace. This state mismatch allows an attacker to insert attributes that are normalized safely by the sanitizer but execute as arbitrary JavaScript when rendered inside the browser's real DOM.

Code Analysis

Prior to the patch in version 7.1.0, TinyMCE's html/Parser.ts maintained a basic state machine to validate nodes against the schema. Below is a conceptual representation of the vulnerable state tracking compared to the corrected stack-based architecture.

// VULNERABLE LOGIC (Pre-7.1.0 Conceptual Representation)
class VulnerableParser {
  private inSvg: boolean = false;
 
  parseNode(node: Token) {
    if (node.name === 'svg') {
      this.inSvg = true; // Flattens nesting context
    } else if (node.name === '/svg') {
      this.inSvg = false; // Prematurely terminates on nested closing tags
    } 
    
    // Sanitization decisions are made using the flawed state
    if (this.inSvg) {
      this.validateSvgAttribute(node);
    } else {
      this.validateHtmlAttribute(node);
    }
  }
}

The corrected implementation introduced in 7.1.0 replaces simple boolean toggles and shallow counters with a robust stack tracker. This tracker perfectly mirrors the browser's namespace switching mechanics, validating HTML integration points like <desc> and <title> explicitly.

// PATCHED LOGIC (Post-7.1.0 Stack-Based Namespace Tracking)
class PatchedParser {
  private namespaceStack: string[] = ['html'];
 
  parseNode(node: Token) {
    const currentNamespace = this.getCurrentNamespace();
 
    if (node.name === 'svg') {
      this.namespaceStack.push('svg');
    } else if (node.name === '/svg') {
      if (this.namespaceStack.includes('svg')) {
        // Correctly pop until the corresponding SVG scope is resolved
        this.popToScope('svg');
      }
    } else if (this.isHtmlIntegrationPoint(node.name) && currentNamespace === 'svg') {
      this.namespaceStack.push('html');
    } else if (node.name === `/${node.name}`) {
      this.namespaceStack.pop();
    }
    
    this.validateNodeUnderNamespace(node, this.getCurrentNamespace());
  }
 
  private getCurrentNamespace(): string {
    return this.namespaceStack[this.namespaceStack.length - 1] || 'html';
  }
}

The implementation of this stack ensures that the parser tracks the exact depth of the SVG context. This modification prevents mutated HTML content from causing the tokenizer to prematurely exit its sanitized state, neutralizing the desynchronization vector.

Exploitation Methodology

To exploit this vulnerability, an attacker must have permissions to submit HTML content to a web application that relies on TinyMCE for rich text rendering. This typically requires low-privileged credentials (such as a forum member or standard content contributor), though in some implementations, the editor is exposed to unauthenticated guest users.

An attacker can use a payload designed to trigger namespace confusion through nested tags and integration point attributes. Consider the following proof-of-concept payload:

<svg><svg><desc><p id="</svg><img src=x onerror=alert(document.domain)>"></p></desc></svg></svg>

The exploitation flow proceeds as follows:

  1. Injection: The attacker inserts the raw HTML payload into the editor's source window.
  2. Sanitization Phase: TinyMCE processes the payload. When encountering <desc>, its internal parsing state fails to recognize the HTML integration boundary correctly. The custom parser views </svg> inside the id attribute as an actual ending token instead of an attribute value. It incorrectly treats the following <img> tag as nested, valid HTML. Because the sanitizer assumes the browser will interpret this sequence safely, it processes the tags and outputs them without removing the dangerous onerror handler.
  3. Browser Execution: The sanitized string is returned and injected into the application's DOM. The browser's native parser parses <desc> as an HTML integration point. It parses <p> as a standard HTML element and evaluates id="</svg><img src=x onerror=alert(document.domain)>" as a literal, benign string attribute. However, if the payload undergoes subsequent serialization steps (such as mutation XSS operations inside the application), the browser's parser is forced to reconstruct the node, releasing the embedded <img> tag into the active namespace and executing the alert() script.

Impact Assessment

The security impact of CVE-2026-47760 is evaluated as High. A successful exploit allows arbitrary JavaScript execution within the target's active session. This vector leads to several high-severity consequences, including session hijacking through the theft of unencrypted session cookies or LocalStorage tokens.

Additionally, attackers can perform unauthorized API operations on behalf of the victim. If an administrative user views the malicious content, the injected script can silently execute administrative functions, such as creating new privileged users, changing configuration settings, or exporting proprietary data.

The vulnerability has a CVSS v3.1 base score of 8.7. The scoring breakdown reflects standard high-impact network vulnerabilities: Network attack vector (AV:N), Low attack complexity (AC:L), Low privileges required (PR:L), and Required user interaction (UI:R). Because the script executes outside the boundaries of the text editor, the vulnerability changes the operational scope (S:C), resulting in High confidentiality and integrity compromises (C:H/I:H).

Remediation and Workarounds

The primary and most effective remediation is upgrading the TinyMCE editor component to version 7.1.0 or higher. For applications still running on older branches, ensure the library is updated to a patched version that incorporates the stack-based parser changes.

If upgrading immediately is not technically feasible due to dependency lock-ins, developers can apply a temporary workaround by disabling SVG and MathML elements completely within the TinyMCE initialization parameters. This configuration forces the editor to discard the tags responsible for namespace desynchronization before they reach the parser module:

tinymce.init({
  selector: 'textarea',
  invalid_elements: 'svg,math,desc,title,metadata,foreignobject'
});

Additionally, implementing a server-side sanitization layer acts as an effective secondary line of defense. The application backend should process all submitted user data using a secure, spec-compliant parsing library (such as DOMPurify) before storing it in persistent databases or outputting it to clients.

Technical Appendix

CVSS Score
8.7/ 10
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:N
EPSS Probability
0.03%
Top 90% most exploited

Affected Systems

TinyMCE core editor librarytinymce npm packageTinyMCE NuGet packagetinymce/tinymce Packagist package

Affected Versions Detail

Product
Affected Versions
Fixed Version
TinyMCE
Tiny Technologies Inc.
>= 6.8.0, < 7.1.07.1.0
AttributeDetail
CWE IDCWE-79
Attack VectorNetwork
CVSS v3.1 Score8.7
EPSS Score0.00033
Exploit Statuspoc
KEV StatusNot Listed

MITRE ATT&CK Mapping

T1190Exploit Public-Facing Application
Initial Access
CWE-79
Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')

The application does not neutralize or incorrectly neutralizes user-controlled input before it is placed into web pages, allowing executable JavaScript code to run in a client browser session.

Vulnerability Timeline

Vulnerability publicly disclosed and CVE-2026-47760 registered
2026-05-28
GitHub Security Advisory GHSA-mh5m-5hw4-5c69 published by maintainers
2026-05-28
TinyMCE version 7.1.0 released containing the core parser fix
2026-05-28
NVD and CVE.org records updated with verified scoring
2026-06-02
Comprehensive technical research and exploit analysis completed
2026-06-05

References & Sources

  • [1]GitHub Security Advisory GHSA-mh5m-5hw4-5c69
  • [2]NVD - CVE-2026-47760 Detail
  • [3]CVE.org Record
  • [4]TinyMCE Primary GitHub Repository
  • [5]Wiz Vulnerability Database Reference
  • [6]Security Researcher Profile (maple3142)
  • [7]maple3142 Technical Blog

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•about 3 hours ago•CVE-2026-47759
8.7

CVE-2026-47759: Stored Cross-Site Scripting (XSS) via Unsanitized data-mce-* Serialization Bypass in TinyMCE

CVE-2026-47759 is a critical stored Cross-Site Scripting (XSS) vulnerability affecting multiple active branches of the TinyMCE rich text editor. The flaw resides in the editor's handling of user-controlled, prefixed internal attributes, such as data-mce-href, data-mce-src, and data-mce-style. When processing raw HTML inputs, TinyMCE's internal validation schema neglects to inspect these custom prefixed attributes. During HTML serialization, the editor's engine extracts these unsanitized values and copies them back into standard executable attributes, overwriting any previously sanitized standard values and leading to execution of arbitrary code.

Amit Schendel
Amit Schendel
8 views•7 min read
•about 4 hours ago•CVE-2026-47762
8.7

CVE-2026-47762: Stored Cross-Site Scripting (XSS) in TinyMCE Protect Pattern Restoration

A high-severity stored Cross-Site Scripting (XSS) vulnerability was identified in the TinyMCE rich text editor. The flaw exists in the handling of the 'protect' configuration option, where forged placeholder comments containing malicious payloads bypass the editor's sanitization routines and execute arbitrary JavaScript during serialization and content restoration.

Amit Schendel
Amit Schendel
7 views•8 min read
•about 4 hours ago•CVE-2026-47742
6.5

CVE-2026-47742: Missing Authorization and Client-Side Property Tampering in Shopper E-commerce Panel

An authorization bypass and client-side property tampering vulnerability (CVE-2026-47742) in the Shopper headless admin panel (built on Laravel and Livewire) allows low-privileged users to modify arbitrary product records (Insecure Direct Object Reference). This occurs due to unlocked public model properties and a complete lack of access control checks on mutating sub-form store methods.

Amit Schendel
Amit Schendel
6 views•5 min read
•about 5 hours ago•CVE-2026-47745
6.5

CVE-2026-47745: Missing Authorization in Shopper Admin Panel Settings

Shopper is an open-source headless e-commerce administration panel built on Laravel, Livewire, and Filament. Prior to version 2.8.0, the admin tables for PaymentMethods, Currencies, and Carriers exposed inline toggles and per-record actions that could be modified by any authenticated user without verifying the corresponding administrative permissions on the backend.

Alon Barad
Alon Barad
5 views•6 min read
•about 5 hours ago•CVE-2026-47715
3.1

CVE-2026-47715: Insecure Direct Object Reference (IDOR) / Cross-Project Authorization Bypass in Bugsink

An Insecure Direct Object Reference (IDOR) vulnerability in Bugsink (versions < 2.2.0) allows authenticated users with access to at least one project to view sensitive event details (including stack traces, local/environment variables, and execution breadcrumbs) belonging to other projects, by supplying a known event UUID directly to the issue event URL paths.

Alon Barad
Alon Barad
4 views•7 min read
•about 6 hours ago•CVE-2026-47716
3.1

CVE-2026-47716: Broken Object Level Authorization in Bugsink Bulk Issue Actions

Bugsink prior to version 2.2.0 is vulnerable to Broken Object Level Authorization (BOLA). The issue list view authorizes access based on the project in the URL path but applies requested bulk actions to submitted issue UUIDs globally, without verifying project ownership.

Amit Schendel
Amit Schendel
4 views•6 min read