CVE-2026-47759: TinyMCE-Stored-XSS über data-mce-*-Attribute — warum der Rich-Text-Editor in jedem PHP-Admin-Backend jetzt eine Lieferketten-Schicht ist
29. Mai 2026. TinyMCE hat gestern mit den Releases 5.11.1, 7.9.3 und 8.5.1 mehrere Stored-XSS-Befunde geschlossen — der prominenteste ist CVE-2026-47759 (CVSS 8.7, high) über unsanitierte data-mce-href-, data-mce-src- und data-mce-style-Attribute. Der Bug nutzt eine bei TinyMCE dokumentierte Eigenschaft: der Editor schreibt diese internen Bookkeeping-Attribute beim Serialisieren in die sichtbaren href/src/style-Werte zurück und überschreibt damit ein vorher von einem HtmlPurifier-/DOMPurify-Sanitizer als sauber eingestuftes Markup. TYPO3-Stamm-Installationen sind nicht betroffen (CKEditor 5 statt TinyMCE), und Sonata-Admin, Sylius und Drupal liefern jeweils CKEditor als Default; betroffen sind primär WordPress-Sites mit aktivem Classic-Editor-Plugin sowie individuelle PHP-Backends, die TinyMCE direkt eingebunden haben. Für die Mittelstands-Lieferkette heißt das: der Rich-Text-Editor ist ab heute eine eigene Schicht im SBOM neben den Composer- und npm-Dependencies.

TL;DR — die 90-Sekunden-Zusammenfassung
- Was wurde veröffentlicht?
CVE-2026-47759 (GHSA-Disclosure 28.05.2026), eine Stored-Cross-Site-Scripting-Schwachstelle im TinyMCE-Rich-Text-Editor. Im gleichen Release-Zyklus auch CVE-2026-47761 (high, weitere Stored-XSS-Klasse) und CVE-2026-47762 (medium,
mce:protected-Kommentare mit aktivierterprotect-Option). Die hier behandelte Klasse: ein Angreifer mit Editor-Rechten kann JavaScript-Payload indata-mce-href-,data-mce-src- unddata-mce-style-Attribute schreiben; beim nächsten Serialisierungs-Lauf kopiert TinyMCE diese Werte zurück in die sichtbarenhref/src/style-Attribute und überschreibt damit ein zuvor durch einen externen Sanitizer als „sauber“ eingestuftes Markup.- Wie schwer?
Hoch (CVSS 8.7). Die Authentifizierungsschwelle ist „Editor-Rechte“ — also Redakteurs- oder Autor-Login, der laufend Texte in den Editor einpflegt. In jedem Mehr-Redakteurs-CMS, in dem Beiträge zwischen Rollen wandern (Autor → Redakteur → Veröffentlichung), ist der Klassenpfad real. Vom Eintritts-Konto aus wird der Stealer-Payload an die Cookies und Tokens jeder höher-priviligierten Rolle und ggf. jedes Frontend-Besuchers exfiltriert, sobald das Markup in einem Render-Lauf gelandet ist.
- Welche TinyMCE-Versionen sind betroffen?
Alle Versionen vor 5.11.1, 7.9.3 und 8.5.1 — also die laufenden Stable-Branches 5.x (LTS-Pflege), 7.x (Vorgänger-Major) und 8.x (Current-Major). Fix: Heben auf 5.11.1, 7.9.3 oder 8.5.1, plus Audit-Lauf aller persistierten Beiträge auf bereits eingeschleuste
data-mce-href/-src/-style-Werte.- Bin ich als Moselwal-Kunde betroffen?
Moselwal-eigenen TYPO3-Stack betrifft das nicht — wir liefern TYPO3 mit CKEditor 5 (rte_ckeditor seit v8 LTS), nicht TinyMCE. Im PHP-Stack sind die Default-Editoren überwiegend CKEditor: Sonata-Admin nutzt CKEditor über
SonataFormatterBundle+FOSCKEditorBundle, Sylius nutzt CKEditor überFOSCKEditorBundle, Drupal 10 liefert CKEditor 5 als Default (TinyMCE existiert nur als Kontrib-Modul für Drupal 8/9). Direkt betroffen sind Sie, wenn auf Ihrer Plattform eine der folgenden Stellen TinyMCE trägt: WordPress-Sites mit aktivem Classic-Editor-Plugin (die mit Abstand größte betroffene Klasse weltweit), individuell entwickelte PHP-Admin-Backends, Third-Party-SaaS-Admins (Newsletter, Helpdesk, Wiki-Engines), oder ein Sonata-/Sylius-/Drupal-Setup, in dem TinyMCE als bewusste Alternative zu CKEditor konfiguriert ist.- Sofort-Mitigation?
Drei Schritte. Erstens, TinyMCE-Version im jeweiligen Backend prüfen und auf 5.11.1, 7.9.3 bzw. 8.5.1 (oder höher) heben — Composer-Paket
tinymce/tinymcebzw. npm-Pakettinymceaktualisieren. Zweitens, Audit-Sweep auf gespeicherte Inhalte: Datenbank-Suche nach den drei Attribut-Strings (data-mce-href,data-mce-src,data-mce-style) in allen RTE-Feldern, manuelle Prüfung der Fundstellen auf eingeschleustejavascript:-URLs,expression()-Konstrukte oder externe Script-Hosts. Drittens, Content-Security-Policy für die Editor- und Veröffentlichungs-Domain auf striktenscript-src 'self'setzen.- Kritikalität?
Siehe Hero-Badge
high— handeln im 48h-Fenster, weil die Disclosure den Bug öffentlich beschreibt und der Sanitizer-Bypass nachvollziehbar ist. Aktive Ausnutzung in der Wildbahn ist Stand Bot-Lauf nicht dokumentiert; CISA-KEV-Aufnahme nicht erfolgt.
Was ist passiert
Tiny Technologies (früher Ephox, Hersteller von TinyMCE) hat am 28. Mai 2026 mit den drei parallelen Releases 5.11.1 (LTS-Branch), 7.9.3 (Vorgänger-Major) und 8.5.1 (Current-Major) mehrere Stored-XSS-Befunde im Rich-Text-Editor TinyMCE geschlossen. Im selben Release-Zyklus tauchen mindestens drei CVE-Nummern auf: CVE-2026-47759 (CVSS 8.7, high) über data-mce-href/-src/-style-Attribute, CVE-2026-47761 (high) als weitere Stored-XSS-Klasse, CVE-2026-47762 (medium) über mce:protected-Kommentare mit aktivierter protect-Option. Wir konzentrieren uns hier auf CVE-2026-47759 als die methodisch interessanteste und am breitesten getroffene Klasse — die drei betroffenen Attribute sind data-mce-href, data-mce-src und data-mce-style.
Der Mechanismus nutzt das Zusammenspiel zwischen TinyMCE-Editor-Bookkeeping und nachgeschaltetem HTML-Sanitizer. TinyMCE schreibt beim Parsen href-, src- und style-Werte zusätzlich als interne data-mce-href-, data-mce-src- und data-mce-style-Attribute (offizielle Doku: „TinyMCE converts src and href into data-mce-src, data-mce-href and data-mce-style as internal attributes“). Diese Temporär-Attribute sollen by-design beim finalen getContent() wieder entfernt werden, überleben aber bestimmte Roundtrip-Pfade (Speichern, Drag-and-Drop, Copy-Paste, Plugin-Reactivation). In diesen Pfaden serialisiert TinyMCE die data-mce-*-Werte autoritativ in die sichtbaren Attribute zurück. Das ist nicht „by-design für den Endwert“, sondern Hilfsverhalten für interne UI-Roundtrips — und genau diese unsichtbare Schicht hat keine Sanitizer-Prüfung gesehen.
Die Sicherheits-Konsequenz blieb bisher unbemerkt: ein nachgeschalteter HTML-Sanitizer (HtmlPurifier, DOMPurify, eine plattformeigene Allowlist) prüft den href-Endwert, den src-Endwert oder den style-Endwert auf seine Allowlist-Konformität. Eine javascript:-URL fällt durch, eine expression()-Style-Regel fällt durch, ein externer Script-Host fällt durch. Wenn dagegen ein data-mce-href="javascript:..." im Markup überlebt — weil der Sanitizer das Attribut nicht kennt oder es als harmloses Datenattribut durchlässt — und der Server speichert das Markup so in der Datenbank, dann überschreibt TinyMCE den geprüften href-Wert beim nächsten Serialisierungs-Lauf mit der data-mce-href-Payload. Die saubere Prüfung wird hinten herum umgekippt.
Die Patches schließen die Lücke durch eine erweiterte Sanitizing-Logik in der Serialisierungs-Pipeline: TinyMCE prüft jetzt die data-mce-*-Attribute selbst gegen dieselbe Allowlist wie die sichtbaren href/src/style-Werte. Aus Plattformbetreiber-Sicht bleibt aber die zweite Verteidigungslinie zwingend — der nachgeschaltete Sanitizer muss die data-mce-*-Attribute kennen, und das Markup in der Datenbank muss einmal auf bereits eingeschleuste Payload geprüft werden, bevor die Plattform den Update für „abgeschlossen“ erklärt.
Technische Einordnung
Strukturell ist CVE-2026-47759 keine klassische Bug-Klasse, sondern eine Sanitizer-Bypass-Schwachstelle durch ein Design-Differenzial zwischen dem Editor-Bookkeeping und dem nachgelagerten Sanitizing-Layer. Das verallgemeinerbare Pattern: ein Editor persistiert mehr Zustand, als die sichtbare HTML-Oberfläche suggeriert, und ein Sanitizer muss dieses unsichtbare Zustands-Set entweder kennen oder explizit verwerfen. In der Rich-Text-Editor-Welt taucht das Pattern mit unterschiedlichen Mechanismen wiederholt auf — CVE-2018-9861 betraf den CKEditor-Image2-Plugin über präparierte IMG-Elemente (anderer Mechanismus, aber dieselbe Pattern-Klasse „Editor-internes Markup überlebt Sanitizer“), CVE-2023-26149 betraf die quill-mention-Erweiterung über unsanitierte Render-List-Daten. Wer Rich-Text-Editor-Markup in seiner Plattform persistiert, sollte ab heute mit dem Reflex arbeiten, dass Editor-spezifische Hilfs-Attribute eine eigene Audit-Klasse bilden.
Methodisch wichtig ist die Verlagerung des Trust-Boundary. Wer in seinem PHP-Backend HtmlPurifier oder eine eigene Allowlist betreibt und sich auf den href/src/style-Endwert verlässt, hat den Trust-Boundary auf den Endwert gelegt. CVE-2026-47759 zeigt, dass diese Linie für TinyMCE-Markup zu eng gezogen war — die data-mce-*-Attribute gehören in dieselbe Prüfspur. Konkret heißt das: HtmlPurifier-Konfiguration muss HTML.AllowedAttributes so setzen, dass data-mce-*-Attribute entweder komplett verworfen werden (Standard-Hardening) oder explizit dieselbe URI-/CSS-Allowlist anwenden. DOMPurify-Nutzer setzen ADD_URI_SAFE_ATTR und ALLOWED_URI_REGEXP analog. Plattformen mit eigener Allowlist nehmen die data-mce-*-Klasse jetzt in den Allowlist-Code auf.
Die Verbindung zur Lieferketten-Spur der letzten zwei Wochen ist die methodisch interessante Lage. Nach der TanStack-npm-Welle (11.05.), Mini-Shai-Hulud-@antv (19.05.), Nx-Console-VS-Code-Marketplace (18.05.) und dem vpmdhaj-OpenSearch/ElasticSearch-Typosquat (28.05.) zeigt CVE-2026-47759 eine andere Lieferketten-Klasse: nicht eine kompromittierte Distributionsschicht, sondern eine in der Komponente selbst angelegte Vertrauens-Schicht, die nachgelagerten Sicherheits-Layern eine Annahme abnimmt, die diese Layer als sicher gelten lassen. Wer in seinem SBOM bisher nur Composer- und npm-Dependencies führt, hat den Rich-Text-Editor implizit als „Komponente von npm“ abgehakt — er bleibt aber im Webbrowser eine eigene Sicherheits-Domäne, die ihre Trust-Boundary mit dem Plattform-Sanitizer abgleichen muss.
Bedeutung für den Mittelstand
Wir schreiben diesen Post nicht aus eigener Betroffenheit. Moselwal liefert TYPO3 mit CKEditor 5 — der rte_ckeditor-Extension, die seit TYPO3 v8 LTS Default-Editor ist und in v12 auf CKEditor 5 aktualisiert wurde. Unsere TYPO3-Stamm-Installationen tragen kein TinyMCE im Render-Pfad. Im übrigen PHP-Stack der Mittelstands-Welt ist der Befund klar einzugrenzen — und das ist der Punkt, an dem viele Erst-Reflexe daneben liegen.
Erste Klasse, weit verbreitet: WordPress mit aktivem Classic-Editor-Plugin. WordPress liefert seit Version 5.0 den Block-Editor (Gutenberg) als Default, der TinyMCE nicht als zentrale Rich-Text-Engine trägt. Das Classic-Editor-Plugin reaktiviert die TinyMCE-basierte Edit-Post-Oberfläche und ist mit zweistelligen Millionen aktiver Installationen einer der meistgenutzten Reaktivierungs-Pfade für das klassische Editor-Modell. Für einen WordPress-Mandanten ist die Reflex-Frage damit: läuft Classic-Editor, und wie aktuell ist der Editor-Stack.
Zweite Klasse, schmaler: individuell entwickelte PHP-Admin-Backends. Sonata-Admin nutzt CKEditor über SonataFormatterBundle + FOSCKEditorBundle als Default-Editor, Sylius nutzt CKEditor über FOSCKEditorBundle im Standard-Admin, Drupal 10 liefert CKEditor 5 als Default (TinyMCE existiert als Kontrib-Modul für Drupal 8/9, ist für Drupal 10 Stand 05/2026 nicht stabil portiert). In diesen drei Stacks ist TinyMCE nur dann im Bild, wenn das Projekt eine bewusste Entscheidung gegen den Default-Editor getroffen und TinyMCE manuell eingebunden hat — etwa wegen einer Tiny-Cloud-Lizenz oder eines historischen Code-Pfads. Dazu kommen Custom-Admin-Backends, die TinyMCE direkt eingebunden haben, und Third-Party-SaaS-Admins (Helpdesk-Tools, Newsletter-Plattformen, Wiki-Engines), die TinyMCE als Editor-Komponente einbetten.
Compliance-seitig wirkt der Befund auf den Standard-Achsen. DSGVO Art. 32 trifft jede Plattform, deren Editor-Pfad personenbezogene Daten verarbeitet — Customer-Service-Tickets, CRM-Notizen, Newsletter-Beiträge über Empfänger-Segmente, Wiki-Einträge über Mitarbeiter. Ein Stored-XSS-Pfad, der Editor- oder Admin-Cookies exfiltriert, ist nach Anlage 1 zu Art. 32 ein technisches Defizit in der Vertraulichkeit der Verarbeitung. NIS-2 Art. 21 fordert Lieferketten-Disziplin in der erweiterten Definition; Rich-Text-Editoren sind nach dieser Definition Komponenten der eingesetzten Software, und ein SBOM, der TinyMCE nicht enthält, führt das Lieferketten-Inventar nicht vollständig. Für DORA-Pflichtige und MaRisk-Häuser sitzt der Editor in der Bewertung der eingesetzten Drittparteien-Komponenten.
Bedeutung für die technische Entwicklung
Architektonisch zwingt CVE-2026-47759 zu einer ehrlichen Inventur des SBOM. Composer- und npm-Pakete sind seit zwei Jahren in fast allen Mittelstands-Pipelines maschinenlesbar — cyclonedx-php-composer, cyclonedx-bom-für-npm, GitHub Dependabot, Mend-ähnliche-Tools. Rich-Text-Editoren laufen oft eine Schicht darunter: sie sind als Composer-Paket installiert (tinymce/tinymce), aber im Application-Code als Komponente innerhalb einer Editor-Wrapper-Bibliothek (z. B. sonata-project/formatter-bundle) verkapselt. Wer den SBOM auf der Composer-Lockfile-Ebene führt, sieht TinyMCE entweder gar nicht oder als Sekundär-Dependency ohne eigenen Risiko-Score. Die Lehre für die Pipeline: SBOM-Tools müssen die transitiven JavaScript-Bundles in der Application explizit auswerfen.
Methodisch sitzt die zweite Lehre in der Trust-Boundary-Diskussion. HtmlPurifier und DOMPurify sind in der PHP- und JavaScript-Welt der Standard-Sanitizer; ihre Default-Konfiguration verbietet script-Tags, javascript:-URLs und CSS-expression()-Konstrukte zuverlässig. Bisher galt der unspoken Konsens: wenn Sanitizer-Konfiguration aktuell ist und Allowlist sauber gesetzt, ist das Editor-Markup unter Kontrolle. CVE-2026-47759 verschiebt diese Annahme — die data-mce-*-Klasse zeigt, dass Editor-Bookkeeping-Attribute zur Sanitizer-Prüfung gehören, auch wenn sie weder im HTML-Standard noch in der Allowlist-Default vorkommen. Die generalisierbare Lehre: Sanitizer-Konfiguration sollte für Rich-Text-Editor-Markup Editor-spezifisch sein und die Bookkeeping-Klassen kennen (CKEditor: data-cke-*, TinyMCE: data-mce-*, Quill: data-quill-*, ProseMirror: data-pm-*). Eine Sanitizer-Config ohne diese Klassen ist nicht „strenger als nötig“, sondern hat einen blinden Fleck.
Drittens, Content-Security-Policy ist die zweite Verteidigungslinie. Wer im Backend Content-Security-Policy: script-src 'self' ohne unsafe-inline setzt, fängt einen überlebten XSS-Pfad in der Browser-Schicht ab, weil eine javascript:-URL aus einem href-Override im Klick keine Ausführung auslösen kann. Diese Disziplin ist in TYPO3-Backends seit v12 Default; in Sonata-Admin- und Drupal-Backends ist sie zu konfigurieren. Wer CVE-2026-47759 als Anlass nimmt, die CSP-Header in den eigenen Admin-Pfaden auf strikten Default zu heben, hat die nächste Sanitizer-Bypass-Klasse schon halb mitgepatcht.
Konkrete Handlungsempfehlung
In dieser Reihenfolge. Erstens, inventarisieren Sie heute, wo in Ihrer Plattform-Landschaft TinyMCE läuft — ein einzelner find . -name "tinymce.min.js" über das Projekt-Asset-Verzeichnis liefert die statisch eingebundenen Pfade, composer why tinymce/tinymce und npm ls tinymce decken die Paket-Pfade ab. Zweitens, für jede Fundstelle: Version prüfen, auf 5.11.1, 7.9.3 oder 8.5.1 heben (je nach Major-Stand), Cache leeren, Editor-Funktion testen. Drittens, Audit-Sweep der persistierten RTE-Inhalte: Datenbank-Suche nach den drei Attribut-Strings (data-mce-href, data-mce-src, data-mce-style) über alle Tabellen mit Rich-Text-Spalten — in WordPress typischerweise wp_posts.post_content und wp_postmeta, in Symfony/Sylius die *_translation-Tabellen mit description/content-Spalten, in Drupal node__body/paragraph__field_text. Manuelle Prüfung der Fundstellen auf javascript:-URLs, externe Script-Hosts und CSS-expression()-Konstrukte. Viertens, Sanitizer-Konfiguration der Plattform prüfen: HtmlPurifier-HTML.AllowedAttributes oder DOMPurify-ALLOWED_ATTR-Listen so setzen, dass data-mce-* entweder vollständig verworfen wird oder dieselbe URI-/CSS-Allowlist durchläuft wie die sichtbaren Attribute. Fünftens, Content-Security-Policy für die Editor-Backends: script-src 'self' ohne unsafe-inline, style-src 'self' mit konkreten Hashes oder Nonces. Sechstens, dokumentieren Sie TinyMCE und alle weiteren Rich-Text-Editoren in Ihrem SBOM-Prozess; wenn Sie keinen haben, ist das der Anlass, einen aufzusetzen. Wenn diese Schritte aus eigener Kraft nicht laufen, sprechen Sie mit uns: Moselwal richtet Plattformen, in denen Rich-Text-Editoren als eigene Lieferketten-Klasse geführt und mit gehärteter Sanitizer- und CSP-Konfiguration betrieben werden.
Dieser Beitrag spiegelt unsere technische und strategische Einschätzung. Er ersetzt keine Rechtsberatung und keine Datenschutz-Folgenabschätzung.
Quellen
- Tiny Technologies — TinyMCE Changelog (Release-Notes 8.5.1 / 7.9.3 / 5.11.1, 28.05.2026)
- tinymce/tinymce — GitHub Security Advisories (CVE-2026-47759 / -47761 / -47762, 28.05.2026)
- The Hacker Wire — TinyMCE Stored XSS: data-mce-* Attribute Bypass (28.05.2026)
- DailyCVE — TinyMCE Stored XSS CVE-2026-47761 (28.05.2026)
- Tiny Technologies — tinymce.dom.Serializer API (Quelle für das interne data-mce-Roundtrip-Verhalten)

