flawopen.com/XSS in JavaScript/DOMPurify and innerHTML
DOMPurify suffit-il à sécuriser innerHTML ?
DOMPurify est un puissant sanitizer à liste d’autorisation pour le HTML riche si sa sortie est insérée directement dans un sink HTML sans modification ultérieure. Imaginez un colis contrôlé au quai : si un autre processus le réemballe ou l’achemine par une autre entrée, le contrôle initial ne couvre plus son contenu. Pour du texte brut, utilisez textContent sans interpréter de HTML.
// Sanitisation à l’enregistrement avec une ancienne version/politique. saveToDb(DOMPurify.sanitize(input)); // Le rendu fait ensuite confiance à la valeur enregistrée. el.innerHTML = fetchedFromDb;
// Si du HTML riche est nécessaire, utilisez la version actuelle // juste avant l’insertion dans le contexte HTML. el.innerHTML = DOMPurify.sanitize(untrustedHtml, { USE_PROFILES: { html: true }, }); // Pour du texte brut, ne l’interprétez pas comme du HTML. textNode.textContent = untrustedText;
Pourquoi une sanitisation unique à l’enregistrement est moins robuste
Sanitiser à l’enregistrement n’est pas forcément dangereux, mais crée une frontière de données anciennes : un rendu peut faire confiance à une sortie antérieure après une correction du sanitizer, un changement de politique ou un chemin qui a omis l’étape. Re-sanitisez au rendu avec la version actuelle et la politique du sink précis. Ne modifiez pas le balisage nettoyé et ne le faites pas passer par une autre bibliothèque avant insertion : le post-traitement peut annuler la sanitisation.
La configuration et le contexte de sortie comptent
La configuration par défaut de DOMPurify autorise HTML, SVG et MathML. Si seul le HTML est nécessaire, limitez le profil avec USE_PROFILES: { html: true }. N’élargissez pas les balises ou attributs sans revue. DOMPurify ne sanitize pas le CSS et n’empêche pas toutes les requêtes externes ; gardez la sortie dans le contexte HTML, sans la réutiliser en JavaScript, attribut, XML, SVG ou CSS.
Trusted Types et rendu côté serveur
Quand c’est pris en charge, imposez Trusted Types avec une Content Security Policy afin de rejeter les chaînes affectées aux sinks HTML sans politique approuvée. DOMPurify peut produire TrustedHTML ; cela réduit les affectations accidentelles, mais ne corrige ni une configuration risquée ni le post-traitement. Côté serveur, DOMPurify dépend d’un DOM : maintenez jsdom à jour et ne l’associez pas à happy-dom pour une sanitisation sensible à la sécurité.
Liste de contrôle de production
- ✓Utilisez textContent pour du texte brut. Utilisez DOMPurify uniquement si le produit doit afficher un sous-ensemble contrôlé de HTML riche.
- ✓Sanitisez au sink HTML final avec la version actuelle de DOMPurify et une liste d’autorisation minimale revue ; ne modifiez pas ensuite le balisage obtenu.
- ✓Conservez la sortie dans un contexte HTML. Ne la réutilisez pas en JavaScript, CSS, attribut, XML, SVG ou autre contexte de parsing.
- ✓Examinez ensemble setConfig() persistant, hooks, ADD_TAGS/ADD_ATTR, versions DOM côté serveur et politiques/CSP Trusted Types.
Rechercher les sinks HTML
rg -n -g '*.{js,ts,jsx,tsx}' '(innerHTML|outerHTML|insertAdjacentHTML|document\.write|dangerouslySetInnerHTML)' .Sources et références
- DOMPurify — README et configuration
- DOMPurify — objectifs de sécurité et modèle de menace
- OWASP — prévention du XSS basé sur le DOM
- OWASP — sécurité JavaScript et TypeScript
- FlawOpen — XSS en JavaScript