Automated Threat Modeling

TinyMCE CVE-2026-47759: Overview of Stored XSS via Internal data-mce-* Attribute Abuse

CVE-2026-47759 is a stored XSS vulnerability in TinyMCE that bypasses sanitization through crafted data-mce-* attributes. This post covers the patch details and the affected versions.

CVE Analysis

7 min read

ZeroPath CVE Analysis
ZeroPath CVE Analysis

2026-05-28

TinyMCE CVE-2026-47759: Overview of Stored XSS via Internal data-mce-* Attribute Abuse
Experimental AI-Generated Content

This CVE analysis is an experimental publication that is completely AI-generated. The content may contain errors or inaccuracies and is subject to change as more information becomes available. We are continuously refining our process.

If you have feedback, questions, or notice any errors, please reach out to us.

[email protected]

Introduction

A stored cross-site scripting vulnerability in TinyMCE lets attackers smuggle malicious payloads through internal data-mce-* attributes and bypass the editor's DOMPurify-based sanitization entirely. The vulnerability has a CVSS score of 8.7. TinyMCE has more than 20 million npm downloads, so the flaw affects a large share of the web applications where rich text editing is a core feature.

TinyMCE, developed by Tiny Technologies (formerly Ephox Corporation), is one of the most widely deployed open-source WYSIWYG rich text editors. It is embedded in CMS platforms, enterprise applications, and SaaS products in almost every industry, so a sanitization bypass in TinyMCE can spread to thousands of downstream applications.

Technical Information

The root cause of CVE-2026-47759 is a trust-boundary gap between TinyMCE's internal attribute handling and its external sanitization layer.

How data-mce-* Attributes Work

When TinyMCE loads content into the editor, it copies the values of certain critical HTML attributes (href, src, and style) into corresponding internal attributes: data-mce-href, data-mce-src, and data-mce-style. These internal copies are the "source of truth" during serialization, when the editor converts its internal DOM back into an HTML string for output. The design assumed that only TinyMCE's own trusted internal logic would ever populate these data-mce-* attributes.

The Sanitization Gap

Since TinyMCE 6.0, the editor has used DOMPurify (version 3.x, upgraded to 3.2.6 in TinyMCE 8.0.1) and the native DOMParser API for HTML sanitization. DOMPurify sanitizes standard HTML attributes like href, src, and style effectively. The data-mce-* attributes, though, are custom data attributes outside DOMPurify's default sanitization scope, and DOMPurify treats them as harmless because in standard HTML they are inert.

TinyMCE's parser did not strip or validate data-mce-* attributes that were already present on inbound content. An attacker could craft HTML that carried malicious data-mce-href, data-mce-src, or data-mce-style values before TinyMCE ever loaded it. Nothing sanitized these attributes on ingestion, so the attacker-supplied values persisted in the editor's internal DOM.

The Override During Serialization

During serialization, TinyMCE reads the data-mce-* values and uses them to overwrite the corresponding sanitized href, src, or style attributes in the output HTML. The attacker's values replace the safe, validated ones and bypass all the sanitization that had been applied to the standard attributes.

Attack Flow

  1. Craft malicious content: The payload goes in a data-mce-* attribute. For example, an element might have a safe, validated href attribute alongside a data-mce-href attribute containing a javascript: URI or another malicious value.

  2. Submit to target application: The content reaches a web application that uses TinyMCE through a content creation form, an API endpoint, or any other input that feeds into the editor.

  3. Sanitization bypass on load: When TinyMCE loads the content, DOMPurify sanitizes the standard HTML attributes (href, src, style) as expected. The data-mce-* attributes pass through unsanitized because they fall outside DOMPurify's scope.

  4. Malicious override on serialization: When the content is serialized for storage or display, TinyMCE's serializer copies the data-mce-href, data-mce-src, or data-mce-style values over the corresponding standard attributes. The malicious values now sit in the href, src, or style positions of the final HTML.

  5. Stored XSS execution: When another user views the stored content, the malicious attribute values execute in that user's browser context.

This is a particularly interesting class of vulnerability because it exploits the gap between two trust boundaries. DOMPurify trusts that data-mce-* attributes are harmless custom data attributes, and TinyMCE's serializer trusts that they contain values it set itself. Neither system validates the other's assumptions.

Broader Scope

The TinyMCE 7.9.3 changelog also lists a separate security fix for "stored XSS vulnerability using media plugin data-mce-object." The data-mce-* attribute sanitization issue may therefore extend beyond the three attributes (data-mce-href, data-mce-src, data-mce-style) named in the primary advisory.

Patch Information

The TinyMCE team released patched versions on May 20, 2026, on three release tracks: 5.11.1 (LTS), 7.9.3, and 8.5.1. The patches are available through npm, NuGet, and Composer.

How the Fix Works

The fix is conceptually elegant. The patched versions strip unsafe data-mce-* attributes during HTML parsing, before the content enters the editor's internal DOM. Because TinyMCE removes any externally supplied data-mce-href, data-mce-src, and data-mce-style attributes at parse time, only values it generates internally can occupy these trusted positions. During serialization, the editor encounters only data-mce-* values that it set itself from already-validated attribute values, which closes the override attack vector entirely.

Upgrade Guidance

The affected version ranges are:

  • All versions prior to 5.11.1
  • All 6.x versions (6.0.0 through 6.8.6)
  • All 7.x versions prior to 7.9.3
  • All 8.x versions prior to 8.5.1

There is no patch available for the TinyMCE 6.x branch. That major version has reached end of life. Users on TinyMCE 6.x must upgrade to either 7.9.3+ or 8.5.1+ to receive the fix. The 5.11.1 LTS patch is available only as part of a commercial long-term support contract. No official workaround exists, so upgrading is the only remediation path.

Affected Systems and Versions

The following TinyMCE versions are vulnerable to CVE-2026-47759:

Version RangeStatus
All versions prior to 5.11.1Vulnerable (patch available via LTS contract)
6.0.0 through 6.8.6 (all 6.x)Vulnerable (end of life, no patch available)
7.0.0 through 7.9.2 (all 7.x before 7.9.3)Vulnerable (upgrade to 7.9.3)
8.0.0 through 8.5.0 (all 8.x before 8.5.1)Vulnerable (upgrade to 8.5.1)

Any web application, CMS, or platform that embeds a vulnerable version of TinyMCE is affected. This includes applications that load TinyMCE via npm, CDN, NuGet, Composer, or bundled distributions.

Vendor Security History

TinyMCE has a documented history of XSS vulnerabilities in its sanitization engine, which suggests a systemic problem in the editor's architecture.

CVE / AdvisoryDescriptionAffected VersionsYear
Bishop Fox AdvisoryXSS in TinyMCE 5.2.15.2.12020
CVE-2024-29203XSS in content insertion codeMultiple2024
CVE-2024-38357XSS in content insertion codeMultiple (including 6.8.0)2024
GHSA-438c-3975-5x3fXSS in iframe handlingMultiple2024
CVE-2026-47759Stored XSS via data-mce-* attributes< 5.11.1, < 7.9.3, < 8.5.12026

These XSS bypasses keep recurring, even after TinyMCE 6.0 adopted DOMPurify. That points to the fundamental difficulty of maintaining a rich text editor that must preserve complex HTML structures while preventing script injection. The data-mce-* attribute pattern is a class of vulnerability in which internal editor metadata becomes an attack surface. The risk is inherent to any editor that uses custom attributes to hold internal state.

HeroDevs has pointed out that TinyMCE 6 is end of life and has unpatched XSS vulnerabilities. The missing 6.x patch for CVE-2026-47759 adds to that concern for organizations still running the branch.

References

Detect & fix
what others miss

Works with
  • GitHub
  • GitLab
  • Bitbucket
  • Azure DevOps Services
  • Gerrit
  • CVS
  • Jira
  • Linear
  • Slack
  • Security Compass
Explore integrations
Security magnifying glass visualization