LabRoundupColumnNews
blog/Articles/From WordPress Editor to Admin Hijack: Four Stored-XSS in TinyMCE, CVE-2026-47759 through 47762
tinymce-cve-2026-47759-47762-stored-xss-quartet-cover-en

From WordPress Editor to Admin Hijack: Four Stored-XSS in TinyMCE, CVE-2026-47759 through 47762

TinyMCE ships four simultaneous stored-XSS fixes (CVE-2026-47759 through 47762, all CVSS 8.7) across data-mce-* attributes, nested SVGs, the media plugin, and mce:protected comments. Patch to 8.5.1, 7.9.3, or 5.11.1 LTS now.

News Updated today
avatar-m-1

Makoto Horikawa

Backend Engineer / AWS / Django

2026.05.298 min3 views
Key takeaways

TinyMCE ships four simultaneous stored-XSS fixes (CVE-2026-47759 through 47762, all CVSS 8.7) across data-mce-* attributes, nested SVGs, the media plugin, and mce:protected comments. Patch to 8.5.1, 7.9.3, or 5.11.1 LTS now.

Hold a WordPress "Editor" or "Contributor" account, and you can hijack an Administrator session — that is the practical effect of four stored cross-site scripting (XSS) vulnerabilities just disclosed in TinyMCE: CVE-2026-47759 through CVE-2026-47762, all rated CVSS 8.7 (High).

TinyMCE built its name as the heart of WordPress's classic editor and is still bundled into WordPress core, countless WordPress plugins, and many commercial themes. The blast radius is not limited to WordPress, however: Joomla, Drupal, Umbraco, Shopify, HubSpot, Statamic, and many bespoke CMS / SaaS admin consoles all rely on TinyMCE, and the same "editor-to-admin" path opens everywhere TinyMCE is embedded.

Fixed builds shipped across three concurrent branches: 8.5.1, 7.9.3, and 5.11.1 (LTS), disclosed on May 28, 2026. The vulnerabilities are not (yet) in CISA KEV at the time of writing, but given how deep TinyMCE sits in the open-source content-editor supply chain, this is worth one explicit sweep of your own stack.

Why a TinyMCE bug is not an isolated issue

TinyMCE is the JavaScript library that puts the familiar "blog editor" UI in your browser, takes rich text from a user, and persists it as HTML for later rendering. As Tiny's own marketing blog notes, the project built its reputation as WordPress's classic editor and is now embedded in Joomla, Umbraco, Shopify, HubSpot, Statamic, and countless smaller CMS projects.

In Japan and elsewhere, TinyMCE turns up in in-house CMSes, internal wikis, helpdesk article editors, customer-support SaaS dashboards, and education platforms. WordPress alone accounts for roughly 59.5% of all sites with an identifiable CMS (41.9% of all websites), so even indirect exposure to TinyMCE patches is not trivial in scale.

How far one editor account actually reaches

"XSS gives you admin" tends to get read as "they get root on the server." That is not what happens here. Map the boundary first.

LayerReached by this 4-CVE batch?Condition
① CMS
admin rights
✅ Almost certainlyTriggered the moment
an admin views the post
② RCE under
the web-server
process
⚠️ Effectively yes
(WordPress and similar)
CMS admin → theme /
plugin upload → arbitrary
PHP execution
③ Host OS
root access
❌ Not from this aloneRequires a separate local
privilege escalation (LPE)
vulnerability

Layer ①, CMS admin takeover, is what these four CVEs directly buy. The flow is: a low-privilege editor — a contributor, junior reporter, or support rep — saves a malicious payload inside a draft. The moment an admin, editor-in-chief, or executive opens that draft to preview or review it, arbitrary JavaScript runs in their browser. What gets stolen is concrete: that admin's session cookie, JWT, or CSRF token. From that point on, the attacker walks into /wp-admin, /admin, or /manage "as a legitimate administrator". Everything the CMS lets an admin do, the attacker can do: edit or delete articles, add users, exfiltrate the member database (email addresses, postal addresses), read out external API secrets like Algolia keys, and pull Slack webhook URLs — all within CMS-admin scope.

Layer ②, RCE under the web-server process, follows because most CMS designs treat "admin can write PHP" as a feature. WordPress is the canonical example: anyone in the admin console can drop a PHP file via the theme editor or a plugin upload, and that code executes under the www-data or nginx process. Drupal, Joomla, and most homegrown CMSes leave the same path open. In practice that means "CMS admin" and "arbitrary code execution under the web-server process" are effectively the same thing. Reads and writes inside /var/www, direct database connections, log file writes, and access to inter-server SSH keys all open up from here.

Layer ③, host OS root, is not reachable from these CVEs alone. Getting from web-server-process privileges to host root requires a separate vector — a Linux kernel local privilege escalation, a misconfigured sudo entry, a SUID binary, etc. Remember the line: "the CMS falls, but the host itself only falls if another CVE is added."

The buyers for layer ① and ② access are not contest hackers — they have clear monetization paths. Industrial spies who join a competitor's CMS as a "contributor" to lift unpublished drafts and internal memos, scam crews that plant fake login overlays inside helpcenter articles to harvest e-commerce customer session cookies in bulk, ransomware precursors who buy a junior reporter's account and wait for the editor-in-chief's preview to grab the admin session, and Initial Access Brokers paying off a wiki-editing contractor to poison an internal knowledge page that every employee eventually opens — that is the demand side. The common thread is that none of these buyers want host root. They want the CMS and the content database, and these four CVEs sit right on that demand vector.

Behind a CVSS 8.7 score, what a CMS operator really shoulders is an admin-session takeover starting from one editor account; content-database exfiltration and tampering pivoting off that takeover; on CMSes where "admin equals PHP execution," writes into the server file system and direct database access downstream; second-order harm reaching ordinary readers through published articles; and the public-accountability chain that follows from "our site was used as a stepping stone."

The four CVEs, one by one

All four CVEs share the same root cause family — the TinyMCE sanitizer letting something through — but the bypass paths differ.

CVE-2026-47759: data-mce-* attribute sanitization gap

CVE-2026-47759 abuses TinyMCE's internal-use attributes data-mce-href, data-mce-src, and data-mce-style. These were treated as editor-internal and largely skipped by the same sanitization that protects ordinary href/src attributes. Instead of fighting the sanitizer head-on, an attacker writes the payload into data-mce-*, and the malicious value is reintroduced into the DOM during the save-then-restore cycle. Affected ranges: 5.x < 5.11.1 / 7.x < 7.9.3 / 8.x < 8.5.1.

CVE-2026-47760: nested-SVG namespace bypass

CVE-2026-47760 turns on the sanitizer's mishandling of SVG namespace scoping: nesting an SVG inside an SVG makes attribute sanitization stop working as expected. Found by DEVCORE researcher maple3142, the fix required rewriting that part of the sanitizer. Affected range: 6.8.0 up to but not including 7.1.0; the root rewrite shipped in 7.1.0.

CVE-2026-47761: media-plugin route to the same data-mce-* injection

CVE-2026-47761 is the same "data-mce-* stored XSS" family as 47759, but the injection path is the media plugin — the official plugin that handles YouTube/Vimeo embeds. Pasting a crafted embed URL goes through the plugin's <mce:object>-style conversion path, which performed loose attribute checks. Affected ranges: 5.x < 5.11.1 / 7.x < 7.9.3 / 8.x < 8.5.1.

CVE-2026-47762: forged mce:protected comments

CVE-2026-47762 targets the "protected comment" mechanism — TinyMCE temporarily shelves things like raw script tags into <!--mce:protected ...--> HTML comments. By forging comments that look like genuine protected ones, an attacker gets them restored straight into the DOM with no further check, executing arbitrary script. The fix now validates decoded protected comments against the configured protect regex rules before restoring them. Affected ranges span four generations: < 5.11.1, 6.0.0 to 6.8.6, 7.0.0 to 7.9.3, and 8.0.0 to 8.5.1.

Version impact matrix

Match your shipped TinyMCE version to each CVE at a glance.

CVE5.x6.x7.x8.x
CVE-47759< 5.11.1 affectednot affected< 7.9.3 affected< 8.5.1 affected
CVE-47760not affected≥ 6.8.0 affected< 7.1.0 affectednot affected
CVE-47761< 5.11.1 affectednot affected< 7.9.3 affected< 8.5.1 affected
CVE-47762< 5.11.1 affected6.0.0–6.8.6 affected< 7.9.3 affected< 8.5.1 affected

Upgrade targets: 8.5.1 for the 8.x branch, 7.9.3 for the 7.x branch, and 5.11.1 for the 5.x LTS branch. The 6.x branch is effectively past mainline support; if you can move 6.x deployments onto 7.x or 8.x, this is a sensible moment to do it.

How to figure out where TinyMCE actually lives in your stack

TinyMCE usually hides in one of four places: your package.json, your composer.json, a CDN reference, or a CMS plugin you didn't write. Sweep them in three passes.

1. Direct dependencies. For npm: npm ls tinymce. For Composer: composer show tinymce/tinymce. For .NET: dotnet list package | grep -i tinymce. Check your bundle logs for the word tinymce too.

2. CDN direct links. Grep your HTML templates for cdn.tiny.cloud or cdnjs.cloudflare.com/.../tinymce. If the CDN URL hardcodes a version number, fixing it is just an edit.

3. CMS plugins and themes. WordPress classic-editor plugins and many commercial themes ship their own TinyMCE bundles. Audit theme and plugin update status. For Joomla, Umbraco, or Statamic, watching upstream CMS patch notes is usually the realistic path.

Timeline

DateEvent
2024 onwardDEVCORE and other researchers continue probing TinyMCE's sanitizer
Oct 2025Root rewrite for the SVG-namespace path lands in TinyMCE 7.1.0
May 28, 2026CVE-2026-47759 through 47762 disclosed; TinyMCE 8.5.1, 7.9.3, 5.11.1 released
May 29, 2026NVD entries published; GitHub Security Advisories updated

Five operational moves to make this week

In priority order.

1. Schedule the version bump. 8.x → 8.5.1, 7.x → 7.9.3, 5.x LTS → 5.11.1. If you're running 5.x LTS without a real LTS reason, this is also a reasonable moment to reconsolidate around 7.x or 8.x.

2. Audit editor accounts. The shared precondition is "stored XSS + a low-privilege editor account." Walk through abandoned freelance contributor accounts, expired contractors, and editor-role members who no longer need write access.

3. Revisit your Content Security Policy. A tight CSP centered on script-src 'self' will absorb stored-XSS landings even if the bug fires. Anything still allowing 'unsafe-inline' without scrutiny is worth revisiting now.

4. IP-restrict and MFA-protect admin consoles. Even if an attacker steals a cookie or JWT via XSS, an admin console limited to corporate IPs / VPN egress, plus MFA, stalls the pivot.

5. Sweep existing content for embedded payloads. These are stored-XSS bugs, so old content may already be carrying payloads. Grep your content database for posts containing data-mce-href, data-mce-src, data-mce-style, nested SVGs, or <!--mce:protected.

Closing: an editor is not "just a UI widget"

Rich-text editors get filed mentally under "the UI thing for bold and italic and image upload," but architecturally they sit on the highest-value path for stored XSS: they take user input, persist it as HTML on the server, and reinstantiate it as DOM in another user's browser. A single weak spot in the sanitizer puts the trust of the entire CMS at risk.

This four-CVE batch is news about four sanitizer bypasses, but it is also news that the TinyMCE maintainers shipped the four fixes cleanly and together. The actual reader homework is small: open your stack and check the TinyMCE version. Slot that single audit into a CMS maintenance window this week.

References