flawopen.com/XSS in JavaScript/DOMPurify and innerHTML
Reicht DOMPurify, um innerHTML sicher zu machen?
DOMPurify ist ein starker Allowlist-Sanitizer für Rich-HTML, wenn die Ausgabe ohne spätere Änderung direkt in einen HTML-Sink gelangt. Wie bei einem Paket am Wareneingang gilt: Wird es danach umgepackt oder über einen anderen Eingang eingeschleust, deckt die erste Prüfung den Inhalt nicht mehr ab. Für normalen Text verwenden Sie textContent statt HTML zu parsen.
// Beim Speichern mit alter Version/Policy sanitisiert. saveToDb(DOMPurify.sanitize(input)); // Später wird dem gespeicherten Wert ungeprüft vertraut. el.innerHTML = fetchedFromDb;
// Wenn Rich-HTML nötig ist, aktuelle Version verwenden // direkt vor dem Einfügen in den HTML-Kontext. el.innerHTML = DOMPurify.sanitize(untrustedHtml, { USE_PROFILES: { html: true }, }); // Reiner Text wird nicht als HTML geparst. textNode.textContent = untrustedText;
Warum einmaliges Sanitizing beim Speichern schwächer ist
Sanitizing beim Speichern ist nicht automatisch unsicher, schafft aber eine Grenze für veraltete Daten: Ein Renderer kann alten Output nach einem Sanitizer-Fix, einer Policy-Änderung oder einem übersprungenen Pfad weiter vertrauen. Sanitizen Sie beim Rendern erneut mit der aktuellen Version und der Policy des konkreten Sinks. Ändern Sie das bereinigte Markup nicht und geben Sie es vor dem Einfügen nicht an eine andere Bibliothek weiter; Nachbearbeitung kann den Sanitizer-Effekt aufheben.
Konfiguration und Ausgabekontext zählen
DOMPurify erlaubt standardmäßig HTML, SVG und MathML. Wenn nur HTML nötig ist, schränken Sie das Profil mit USE_PROFILES: { html: true } ein. Erweitern Sie Tags oder Attribute nur nach Prüfung. DOMPurify ist kein CSS-Sanitizer und verhindert nicht alle externen Anfragen; verwenden Sie die Ausgabe nur im HTML-Kontext, nicht in JavaScript, Attributen, XML, SVG oder CSS.
Trusted Types und serverseitiges Rendering
Erzwingen Sie, sofern unterstützt, Trusted Types über eine Content Security Policy, damit Strings an HTML-Sinks ohne freigegebene Policy abgewiesen werden. DOMPurify kann TrustedHTML liefern; das verhindert versehentliche Sink-Nutzung, behebt aber weder unsichere Konfiguration noch Nachbearbeitung. Serverseitig benötigt DOMPurify eine DOM-Implementierung: Halten Sie jsdom aktuell und kombinieren Sie es für sicherheitskritisches Sanitizing nicht mit happy-dom.
Produktions-Checkliste
- ✓Verwenden Sie textContent für normalen Text. Nutzen Sie DOMPurify nur, wenn das Produkt begrenztes Rich-HTML darstellen muss.
- ✓Sanitizen Sie am endgültigen HTML-Sink mit der aktuellen DOMPurify-Version und einer geprüften minimalen Allowlist; ändern Sie das Ergebnis danach nicht.
- ✓Belassen Sie die Ausgabe im HTML-Kontext. Verwenden Sie sie nicht erneut in JavaScript, CSS, Attributen, XML, SVG oder einem anderen Parserkontext.
- ✓Prüfen Sie gemeinsam persistentes setConfig(), Hooks, ADD_TAGS/ADD_ATTR, serverseitige DOM-Versionen und Trusted-Types-Policy/CSP.
HTML-Sinks im Code suchen
rg -n -g '*.{js,ts,jsx,tsx}' '(innerHTML|outerHTML|insertAdjacentHTML|document\.write|dangerouslySetInnerHTML)' .Quellen und Referenzen
- DOMPurify — README und Konfiguration
- DOMPurify — Sicherheitsziele und Bedrohungsmodell
- OWASP — DOM-basiertes XSS verhindern
- OWASP — JavaScript- und TypeScript-Sicherheit
- FlawOpen — XSS in JavaScript