Introduction
A stored XSS vulnerability in TinyMCE's content protection mechanism lets any authenticated user with editing privileges inject persistent JavaScript that runs in the browser of everyone who views the affected content. CVE-2026-47762 has a CVSS score of 8.7 and a "Scope: Changed" designation, which makes it the most severe vulnerability ever recorded for TinyMCE. All 12 prior CVEs in the editor's history scored lower.
TinyMCE is an open source rich text editor from Tiny Technologies, Inc., used by over 1.5 million developers worldwide. It is embedded in content management systems, CRM platforms, learning management systems, email clients, and SaaS applications, and it is widely considered the default WYSIWYG editor for enterprise web applications. A sanitization bypass in an editor this widespread has a large blast radius: it could affect thousands of downstream applications.
Two companion vulnerabilities, CVE-2026-47761 and CVE-2026-47759, were disclosed with this one, and all three were patched on May 20, 2026. Together they suggest a coordinated sanitization audit by the researcher Ivan Babenko (he1d3n).
Technical information
The protect option and mce:protected comments
CVE-2026-47762 turns on one TinyMCE feature, the protect configuration option. The option takes an array of regex patterns that identify content the editor should preserve verbatim during processing. Common uses are server-side template tags (e.g., <%= ... %>), PHP blocks, and other non-standard markup that the editor's sanitizer would otherwise strip or mangle.
When TinyMCE finds content matching a protect pattern during editing, it encodes that content into special HTML comments using the mce:protected marker format. A protected block might be stored internally like this:
<!-- mce:protected <encoded_content_here> -->
TinyMCE's sanitization pipeline, which has used DOMPurify alongside the native browser DOMParser() since version 6.0, explicitly skips content inside mce:protected comments. It assumes the editor itself put that content there under legitimate protect rules.
On serialization (when content is extracted for saving or display), the editor decodes these comments and restores the original content into the document.
The root cause
The flaw is in the restoration phase. Before restoring decoded mce:protected content, TinyMCE did not check whether it actually matched any of the configured protect regex patterns. The decoder blindly trusted every mce:protected comment it found, whatever its origin.
An attacker therefore did not need to reach the protect mechanism through its intended entry point. They could write forged mce:protected comments containing arbitrary payloads directly. The sanitizer skipped these comments because they looked like legitimate protected content, and the decoder faithfully restored them into the DOM.
Attack flow
The exploit runs in five steps:
-
Payload injection: An attacker with basic content-editing access (any authenticated user in most CMS deployments) crafts HTML containing forged
mce:protectedcomments. These comments wrap malicious JavaScript, such as<script>tags or event handler attributes, encoded in the format TinyMCE expects. -
Sanitizer bypass: When TinyMCE processes this content, the sanitization pipeline reaches the
mce:protectedcomments and skips them entirely. It treats them as trusted, on the assumption that the editor's ownprotectmechanism generated them. -
Persistent storage: The application saves the content, forged comments and malicious payloads included, to its database or content store. That persistence is what makes this a stored (Type 2) XSS vulnerability rather than a reflected one.
-
Content restoration: When any user later views or edits the content, TinyMCE's serialization process decodes the
mce:protectedcomments. Nothing checks the decoded content against the configuredprotectregex patterns, so the forged content is decoded and injected into the DOM. -
Script execution: The attacker's JavaScript runs in the victim's browser session with the victim's privileges. From there the attacker can hijack the session, steal credentials, exfiltrate data, or move laterally within the application.
CVSS breakdown
The CVSS v3.1 vector is CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:N, which scores 8.7. Here is how the individual metrics break down:
| Metric | Value | Significance |
|---|---|---|
| Attack Vector | Network | Exploitable remotely over the internet |
| Attack Complexity | Low | No specialized conditions or race conditions required |
| Privileges Required | Low | Any authenticated user with content editing access |
| User Interaction | Required | Victim must view or interact with the poisoned content |
| Scope | Changed | Impact crosses from TinyMCE into the victim's browser context |
| Confidentiality | High | Full compromise of victim's session data |
| Integrity | High | Attacker can modify data as the victim |
| Availability | None | No direct denial of service impact |
Scope: Changed means the impact extends beyond the vulnerable component (TinyMCE) into a different security authority (the victim's browser session). That one metric lifts the score to 8.7 from what would otherwise land in the 6.x range.
Prerequisite: the protect option
Only TinyMCE deployments that use the protect configuration option are vulnerable. Without it, the mce:protected comment mechanism is inactive and the attack vector does not exist. The narrower scope concentrates the risk, though. Deployments that deliberately use protect tend to be enterprise CMS and document management platforms handling complex templated content.
Patch information
The TinyMCE maintainers shipped a coordinated fix on May 20, 2026, in three supported release branches: 5.11.1, 7.9.3, and 8.5.1. The fix is tracked internally as TINY-14353. TinyMCE 6.x has reached end of life and does not receive a patch, so all 6.x versions (>= 6.0.0, <= 6.8.6) are permanently affected.
The patch adds a validation step to the content restoration phase. According to the official release notes, patched versions now "validate decoded mce:protected content against configured protect regex rules before restoring." The decoder no longer blindly trusts mce:protected comments. After decoding the protected content, the editor checks whether the result matches at least one of the regex patterns in the user's protect configuration. If no pattern matches, which means the comment was forged, the editor rejects the content instead of restoring it into the document.
The fix enforces an allowlist at the point of decode instead of relying only on content sanitization at ingestion, which makes it a clean defense-in-depth approach. The change ships in both the Enterprise/Cloud and Community editions on all patched version lines.
Upgrade paths:
| Current Branch | Upgrade Target | Notes |
|---|---|---|
| TinyMCE 8.x | 8.5.1 or higher | Direct upgrade |
| TinyMCE 7.x | 7.9.3 or higher | Direct upgrade |
| TinyMCE 5.x | 5.11.1 LTS | Requires commercial long-term support contract |
| TinyMCE 6.x | 7.9.3 or 8.5.1 | No 6.x patch exists; must migrate to a supported branch |
The GitHub advisory states that no official workaround is available, so upgrading is the only remediation path.
For defense in depth, Tiny Technologies' own security documentation recommends several supplementary measures:
- Server-side content filtering: The TinyMCE security guide states that "client-side applications can be by-passed by attackers" and recommends "processing received editor content through server-side filters."
- Content Security Policy (CSP): Deploy CSP headers to restrict script execution. For self-hosted deployments, Tiny recommends:
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src 'self'; connect-src 'self' blob:; img-src 'self' data: blob:; style-src 'self' 'unsafe-inline'; font-src 'self';">
TinyMCE currently requires unsafe-inline in the style-src directive, so strict CSP is not fully supported.
- HTTPS with HSTS: Tiny's security team "strongly recommends that customers embedding TinyMCE configure their web servers to include the HTTP Strict Transport Security (HSTS) header."
These measures can reduce the blast radius of any XSS exploit, but they cannot prevent the initial injection.
Affected systems and versions
CVE-2026-47762 affects four major TinyMCE release lines, covering roughly seven years of deployments:
| TinyMCE Branch | Affected Range | Patched Version | Status |
|---|---|---|---|
| 5.x | All versions before 5.11.1 | 5.11.1 | Patch available (commercial LTS only) |
| 6.x | >= 6.0.0 through 6.8.6 (all versions) | None | End of life; no patch will be issued |
| 7.x | >= 7.0.0, before 7.9.3 | 7.9.3 | Patch available |
| 8.x | >= 8.0.0, before 8.5.1 | 8.5.1 | Patch available |
Only deployments that use the protect configuration option are affected by this CVE. Deployments without it are not vulnerable to CVE-2026-47762, but they may still be affected by the two companion vulnerabilities disclosed the same day (CVE-2026-47761 and CVE-2026-47759), which affect broader configurations.
TinyMCE 5.x reached End of Support in April 2023, and the 5.11.1 patch is available only through a commercial long-term support contract.
Vendor security history
TinyMCE has a documented history of XSS vulnerabilities. OpenCVE lists 12 prior CVEs, all classified under CWE-79:
| CVE ID | CVSS | Description | Fixed In |
|---|---|---|---|
| CVE-2019-1010091 | 6.1 | XSS via media element embed tab | 4.7.13+ |
| CVE-2020-12648 | 6.1 | XSS in classic editing mode | 5.2.1+ |
| CVE-2020-17480 | 6.1 | XSS in core parser/paste/visualchars plugins | 4.9.7, 5.1.4 |
| CVE-2022-23494 | 5.4 | XSS in alert/confirm dialogs | 5.10.7, 6.3.1 |
| CVE-2023-45818 | 6.1 | mXSS via undo/redo serialization | 5.10.8, 6.7.1 |
| CVE-2023-45819 | 6.1 | XSS via Notification Manager API | 5.10.8, 6.7.1 |
| CVE-2023-48219 | 6.1 | mXSS via core undo/redo and APIs | 5.10.9, 6.7.3 |
| CVE-2024-29203 | 4.3 | XSS via iframe in content insertion | 6.8.1 |
| CVE-2024-29881 | 4.3 | XSS via SVG in object/embed elements | 6.8.1, 7.0.0 |
| CVE-2024-21908 | 6.1 | Stored XSS via crafted HTML | 5.9.0 |
| CVE-2024-21910 | 6.1 | XSS via crafted image/link URLs | 5.10.0 |
| CVE-2024-21911 | 6.1 | Stored XSS via crafted HTML | 5.6.0 |
At 8.7, CVE-2026-47762 is the highest-severity TinyMCE vulnerability on record, well above the previous ceiling of 6.1. The recurring XSS pattern comes from a basic architectural problem: a rich text editor has to support arbitrary HTML content and still prevent script execution. TinyMCE adopted DOMPurify in version 6.0, and the vendor maintains SOC 2 Type 2 compliance, annual penetration testing, and automated code scanning. Edge cases like the mce:protected comment bypass still surface. The protect mechanism sat outside DOMPurify's sanitization pipeline by design, and that created an unintended escape route.
The three CVEs disclosed together (CVE-2026-47759, CVE-2026-47761, CVE-2026-47762) were all discovered by the same researcher (Ivan Babenko / he1d3n), which suggests a systematic audit of TinyMCE's internal content handling rather than isolated findings. That is a good sign that the vendor is actively investigating and closing sanitization gaps.
References
- NVD: CVE-2026-47762
- CVE Record: CVE-2026-47762
- GitHub Advisory: GHSA-v98h-vmpc-fpqv
- TinyMCE 7.9.3 Release Notes
- TinyMCE 8.5.1 Release Notes
- TinyMCE 8.5.1 Release Notes (latest docs)
- TinyMCE Changelog (latest)
- TinyMCE Changelog (7.x)
- TinyMCE CHANGELOG.md on GitHub
- TinyMCE Security Guide
- SB2026052050: Multiple vulnerabilities in TinyMCE
- TinyMCE CVEs on OpenCVE
- TinyMCE Official Site
- About Tiny Technologies



