ApostropheCMS sanitize-html: Umgehung des SMIL-Animations-Namespace-Präfix ermöglicht javascript: URI-Injection (XSS)
Zusammenfassung
sanitize-html 2.17.7 führte animatesUrlAttribute() ein, um SVG-Animationselemente (animate, animateColor, animateMotion, animateTransform, set) zu blockieren, wenn deren attributeName auf eine URL-Senke wie href abzielt. Diese Prüfung wird jedoch umgangen, wenn das Animationselement ein Namespace-Präfix verwendet (z. B. svg:animate anstelle von animate).
Ursache
Die Funktion animatesUrlAttribute (index.js, Zeile ~832) prüft svgAnimationTags.indexOf(name.toLowerCase()), wobei svgAnimationTags einfache lokale Namen enthält: ["animate", "animatecolor", "animatemotion", "animatetransform", "set"]. htmlparser2 übergibt Tag-Namen mit Namespace-Präfix unverändert, sodass svg:animate nicht mit animate im Array übereinstimmt. Dies führt dazu, dass die Funktion false zurückgibt und der SMIL-XSS-Schutz übersprungen wird.
Ironischerweise verarbeitet die Funktion Namespace-Präfixe für den Zielwert attributeName bereits korrekt (Zeile ~843): const localName = target.slice(target.lastIndexOf(":") + 1) – dieselbe Bereinigung wurde jedoch nicht auf den Tag-Namen selbst angewendet.
Proof of Concept
const sanitizeHtml = require("sanitize-html");
const config = {
allowedTags: false,
allowedAttributes: false,
allowedSchemes: ["http", "https"]
};
// Standard animate — BLOCKED by 2.17.7 fix
const blocked = sanitizeHtml(
`<svg><a href="#safe"><animate attributeName="href" values="#safe;javascript:alert(1)" dur=".01s" fill="freeze"/><text>Click</text></a></svg>`,
config
);
console.log("Standard animate:", blocked.includes("javascript:") ? "BYPASS" : "BLOCKED");
// Output: BLOCKED
// Namespace-prefixed animate — BYPASSES the fix
const bypassed = sanitizeHtml(
`<svg><a href="#safe"><svg:animate attributeName="href" values="#safe;javascript:alert(document.domain)" dur=".01s" fill="freeze"/><text>Click</text></a></svg>`,
config
);
console.log("svg:animate:", bypassed.includes("javascript:") ? "BYPASS" : "BLOCKED");
// Output: BYPASS
Alle 5 SMIL-Animationselemente können mit jedem Namespace-Präfix (svg:, xlink:, xml:, Varianten in Großbuchstaben) umgangen werden. Getestet und bestätigt auf sanitize-html 2.17.7 aus dem apostrophe-Monorepo.
Auswirkungen
Cross-Site-Scripting (XSS) über SMIL-Animations-Retargeting. Wenn eine Anwendung allowedTags: false verwendet (üblich in Rich-Text-Editoren, die SVG beibehalten möchten), kann ein Angreifer <svg:animate attributeName="href" values="#safe;javascript:..." .../> einschleusen, um das href-Attribut eines übergeordneten <a>-Elements nach dem Laden der Seite zu überschreiben, wodurch beim Anklicken des Links JavaScript ausgeführt wird.
Vorgeschlagene Behebung
Entfernen des Namespace-Präfixes aus dem Tag-Namen vor dem Lookup, analog zu dem Muster, das bereits für das Attributnamensziel verwendet wird:
// Before (vulnerable):
if (svgAnimationTags.indexOf(name.toLowerCase()) === -1) {
// After (fixed):
const localTagName = name.toLowerCase().slice(name.lastIndexOf(":") + 1);
if (svgAnimationTags.indexOf(localTagName) === -1) {
Betroffene Versionen
sanitize-html >= 2.17.7 (wo der SMIL-Animationsschutz eingeführt wurde). Frühere Versionen verfügen überhaupt nicht über den SMIL-Schutz.
Danksagung
Kai Aizen (SnailSploit) — Adversarial AI & Security Research
Was zu tun ist
Aktualisieren Sie sanitize-html auf Version 2.18.0 oder höher.
Betroffene Software
Klicken Sie auf eine Technologie, um alle zugehörigen Schwachstellen anzuzeigen.
| Plattform | Paket | Anfällige Versionen | Behoben in |
|---|---|---|---|
| npm-Paket | sanitize-html | >= 2.17.7, < 2.18.0 | 2.18.0 |
Verweise
- https://github.com/apostrophecms/apostrophe/security/advisories/GHSA-374f-7chj-9948
- https://github.com/apostrophecms/apostrophe/commit/9500b8b0e1d630d5e07fbb5fd2c25ed0943845ce
- https://github.com/apostrophecms/apostrophe/commit/f84fd41cbf6c22eb8d0008fc9c25df1f7130b350
- https://github.com/apostrophecms/apostrophe
- https://github.com/apostrophecms/apostrophe/releases/tag/sanitize-html@2.18.0
- CVSS-Vektor
CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:U/C:L/I:L/A:N- Schwäche (CWE)
CWE-79- Plattform
- npm
- Paket
sanitize-html- Veröffentlicht
- 20.10.2026
- Aktualisiert
- 20.10.2026 21:31
Quellen und Lizenzen · Von DockRay bearbeitet oder übersetzt; Rechte und Lizenzen der Quellen bleiben erhalten.
OSV / GitHub Advisory Database - GHSA-374f-7chj-9948 - CC BY 4.0
Schwachstellenhistorie: sanitize-html
Alle veröffentlichten Schwachstellen dieses Pakets (npm-Paket), neueste zuerst. Zeigt, ob es ein einmaliger Ausrutscher ist oder ein Paket, das man im Auge behalten muss.
- Einträge insgesamt
- 15
- Erste → letzte
- 11.2018 10.2026
- Ohne Fix
- 0
- In Angriffen ausgenutzt
- 0
Verteilung nach Schweregrad
- Kritisch 1
- Hoch 1
- Mittel 12
- Niedrig 1
Veröffentlichungen pro Jahr
- 2018: 2
- 2019: 0
- 2020: 1
- 2021: 2
- 2022: 1
- 2023: 0
- 2024: 1
- 2025: 1
- 2026: 7
-
ApostropheCMS sanitize-html: Umgehung des SMIL-Animations-Namespace-Präfix ermöglicht javascript: URI-Injection (XSS) dieser Eintrag
Erkennen Sie Schwachstellen in Ihrer Anwendung
Mit der DockRay-Integration und aktivierter Softwareinventarisierung prüft DockRay gemeldete Komponentenversionen auf bekannte Schwachstellen und benachrichtigt Sie über bestätigte Treffer. Die Abdeckung hängt von der unterstützten Technologie und den verfügbaren Meldungen ab.