Jun 6, 2026·7 min read·92 visits
Unsanitized data-mce-* attributes in TinyMCE allow attackers to bypass HTML sanitization filters, injecting stored XSS payloads that execute during output serialization.
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.
TinyMCE is an industry-standard, platform-independent rich text editor implemented in JavaScript. It relies on a modular architecture that parses raw HTML input, maps it to an editable Document Object Model (DOM) container within the browser, and serializes the modified DOM back into a clean HTML string. Because browsers dynamically resolve paths and execute script blocks, the editor must strictly enforce input validation, protocol sanitization, and output encoding to prevent security regressions.
This vulnerability, classified under CWE-79 (Improper Neutralization of Input During Web Page Generation), represents a stored Cross-Site Scripting (XSS) flow. The attack surface is exposed whenever an application integrates TinyMCE to accept structured user input and subsequently stores or renders the resulting HTML without server-side validation. The vulnerability relies on a fundamental logical disconnect between the input parser's schema validation filters and the output serializer's reconstruction mechanisms.
By leveraging custom-prefixed attributes, an attacker can smuggle active JavaScript payloads past standard client-side filters. The impact is significant because the malicious payload bypasses typical validation layers during initial ingestion and only manifests as an active script vector after serialization is finalized. This behavior allows the exploit to bypass standard detection signatures that only inspect common script-bearing attributes during HTTP submission.
To understand the root cause of CVE-2026-47759, it is necessary to examine how TinyMCE handles path preservation and styling attributes during editing. When a user inputs a relative URL into a rich text editor, the underlying browser engine automatically resolves it to an absolute URL based on the document's host environment. To prevent this behavior and preserve original relative paths for storage, TinyMCE tracks the user's raw intended input using custom attributes, specifically data-mce-href, data-mce-src, and data-mce-style.
During active editing, these attributes operate alongside their standard counterparts. However, during the final HTML generation phase, which is triggered by invoking editor.getContent(), the serialization subsystem uses the tracked values in these data-mce-* attributes to overwrite the standard href, src, and style attributes. This design assumes that the internal attributes are identical to or safer than the standard attributes, or that they have undergone equivalent sanitization.
The vulnerability is introduced because TinyMCE's parser treats custom data-mce-* attributes as harmless data attributes, excluding them from schema-level protocol validation rules. While the parser strictly validates standard href and src attributes (stripping protocols like javascript: or data:), it ignores the custom-prefixed equivalents. Consequently, when the serialization engine executes its overwrite routine, it copies the unchecked, raw payload from the data-mce-* attribute directly into the standard attribute, effectively neutralizing previous sanitization steps.
An analysis of the vulnerability mechanics highlights the logical gap in the serialization pipeline. Prior to the patch, the serialization logic extracted the values of internal attributes and bound them directly to standard elements without validating their protocol or structure. The vulnerable code pathway operated similarly to the following simulation:
// Vulnerable Serialization Routine
function serializeElement(node) {
const dataMceHref = node.getAttribute('data-mce-href');
if (dataMceHref) {
// Vulnerability: Direct assignment without protocol validation
node.setAttribute('href', dataMceHref);
node.removeAttribute('data-mce-href');
}
const dataMceSrc = node.getAttribute('data-mce-src');
if (dataMceSrc) {
node.setAttribute('src', dataMceSrc);
node.removeAttribute('data-mce-src');
}
}The official vendor patches released for versions 5.11.1, 7.9.3, and 8.5.1 address this structural issue by forcing validation of the tracking attributes before mapping them back to standard attributes. The patch ensures that if a tracking attribute contains a restricted protocol, it is either neutralized or stripped entirely during serialization.
// Patched Serialization Routine
function serializeElementPatched(node, schema) {
const dataMceHref = node.getAttribute('data-mce-href');
if (dataMceHref) {
// Patch: Validate the tracking attribute's protocol before assignment
if (schema.isValidUri(dataMceHref, 'href')) {
node.setAttribute('href', dataMceHref);
} else {
// Fallback or stripping mechanism
node.removeAttribute('href');
}
node.removeAttribute('data-mce-href');
}
}While the fix successfully addresses the direct bypass vector in supported versions, users running TinyMCE 6.x are left exposed. Because the 6.x branch has reached its End-of-Life (EOL) milestone, no official patch has been backported to this version range. Organizations using 6.x must manually implement mitigation patterns or complete a structural upgrade to the 7.x or 8.x branches.
To exploit this vulnerability, an attacker must inject structured HTML containing custom data-mce-* attributes. This can be achieved through multiple attack vectors, such as direct API submission, intercepting HTTP POST requests, or exploiting clipboard paste actions if the editor is configured to accept arbitrary HTML formats.
A typical exploit payload targets the hyperlink node. The attacker defines a standard, benign link destination in the href attribute to satisfy basic input-filtering mechanisms, while embedding the malicious scripting instructions inside the data-mce-href attribute:
<a href="https://trusted-site.com" data-mce-href="javascript:alert(document.cookie)">Click here to continue</a>When this markup is initially supplied to the editor, the internal parsing engine validates href and confirms that https://trusted-site.com is a safe, HTTP-based destination. It permits the document to load. When the document is saved or submitted, the backend or client-side wrapper invokes tinymce.activeEditor.getContent(). The serialization process reads data-mce-href and overwrites the existing href value, resulting in the following serialized output:
<a href="javascript:alert(document.cookie)">Click here to continue</a>Once stored in the host application's database, this markup is served to subsequent users. When a victim clicks the link, the browser executes the script in the context of the vulnerable application.
The impact of successful exploitation is stored Cross-Site Scripting, which carries a CVSS 3.1 base score of 8.7. Because the payload is persistent, the execution of arbitrary JavaScript occurs automatically whenever an end-user loads and interacts with the compromised page. This eliminates the need for complex phishing campaigns or social engineering beyond encouraging a user to view a standard page.
The scope of the vulnerability is classified as Changed (S:C) because execution occurs within the host application's domain context rather than the isolated editor iframe. An attacker can access document cookies, session storage tokens, and authorization headers, potentially leading to complete account takeover if session identifiers lack the HttpOnly flag.
Additionally, the scripting context allows attackers to perform actions on behalf of the victim. This includes executing state-changing transactions, modifying profile details, or launching targeted drive-by download operations against administrators. In highly privileged administrative consoles, this execution flow can lead to total application compromise.
The primary remediation for CVE-2026-47759 is updating the TinyMCE library to a patched version. Development teams must identify the active major release branch in use and deploy the corresponding update: version 5.11.1 for 5.x systems, version 7.9.3 for 7.x systems, and version 8.5.1 for 8.x systems. Because the 6.x release branch is EOL, systems on this version must be upgraded to a supported active branch.
To establish a defense-in-depth posture, server-side HTML sanitization should be implemented for all rich text payloads before they are persisted to a database. Server-side sanitization libraries, such as DOMPurify, must be configured to strip custom data-mce-* attributes explicitly to neutralize any client-side parser bypasses.
// Secure Server-Side Sanitization Configuration using DOMPurify
const DOMPurify = require('dompurify');
const { JSDOM } = require('jsdom');
const window = new JSDOM('').window;
const purify = DOMPurify(window);
const cleanHTML = purify.sanitize(userInput, {
FORBID_ATTR: ['data-mce-href', 'data-mce-src', 'data-mce-style']
});Furthermore, organizations should enforce a robust Content Security Policy (CSP) that restricts script execution. Omitting the 'unsafe-inline' directive and implementing script nonces or hashes prevents unauthorized inline script executions, mitigating the impact of any successfully injected XSS payloads.
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
TinyMCE Tiny | < 5.11.1 | 5.11.1 |
TinyMCE Tiny | >= 6.0.0, <= 6.8.6 | None (Upgrade to 7.9.3 / 8.5.1) |
TinyMCE Tiny | >= 7.0.0, < 7.9.3 | 7.9.3 |
TinyMCE Tiny | >= 8.0.0, < 8.5.1 | 8.5.1 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-79 (Improper Neutralization of Input During Web Page Generation) |
| Attack Vector | Network (AV:N) |
| CVSS Base Score | 8.7 |
| Exploit Status | Proof-of-Concept (PoC) Feasible |
| Impact | Stored Cross-Site Scripting (XSS) / Execution of Arbitrary Script |
| KEV Status | Not Listed |
The application does not neutralize or incorrectly neutralizes user-controlled input before it is placed in output that is used as a web page that is served to other users.
An authentication bypass vulnerability exists in the SiYuan personal knowledge management system (versions <= v3.7.2). The flaw occurs because the kernel's authorization validation handler trusts loopback connection origins blindly, allowing remote network attackers to gain administrative privileges via an exposed local reverse proxy.
An information disclosure vulnerability in the SiYuan knowledge management system versions up to and including v3.7.2 allows remote unauthorized attackers to retrieve PDF annotations via the /api/asset/getFileAnnotation endpoint due to missing authorization checks.
CVE-2026-72807 is a second-order SQL injection vulnerability in SiYuan versions prior to v3.7.4. It resides in the dynamic evaluation of Attribute View (AV) template columns, which expose unsafe template functions. An attacker can exploit this by distributing a malicious SiYuan package that executes arbitrary SQL queries on the victim's local database.
An authorization bypass vulnerability in SiYuan prior to v3.7.4 allows unauthenticated remote attackers to access rows, block IDs, and custom attributes of password-protected documents via the attribute view rendering endpoint.
SiYuan Note versions before v3.7.4 fail to enforce publish-access checks on several block API endpoints. This vulnerability allows anonymous readers or authorized accounts with low-privileged roles to retrieve sensitive document titles, ancestor block content snippets, reference text, and path metadata for publish-forbidden or password-protected documents by supplying target block IDs.
SiYuan before version 3.7.4 contains an authentication bypass vulnerability within its graph visualization API endpoints, allowing unauthenticated remote attackers to extract sensitive node metadata and content from password-protected documents.