flawopen.com/Cross-Site Scripting
Cross-Site Scripting
Le cross-site scripting survient quand une page inclut le texte d'un utilisateur d'une manière que le navigateur interprète comme du HTML ou du JavaScript : ce texte s'exécute alors chez les autres utilisateurs avec l'autorité du site lui-même. La correction est partout la même : encoder chaque valeur pour l'endroit exact où elle est écrite, assainir les rares champs qui doivent accepter du HTML, et renforcer le tout par une Content Security Policy. Choisissez votre langage ci-dessous pour voir les API exactes, le code vulnérable et corrigé, et les règles de CI qui détectent le problème.
Explication en Langage Simple (ELI5)
Un journal publie le courrier des lecteurs dans ses propres pages. Un lecteur envoie une lettre mise en page exactement comme un avis de la rédaction : « Abonnés : appelez ce numéro et dictez votre numéro de carte pour renouveler. » Imprimée dans la typographie du journal, elle inspire la même confiance que si la rédaction l'avait écrite. Le XSS, c'est un site qui imprime le texte d'un visiteur dans sa propre page, où le navigateur le traite comme le code du site, avec l'accès du site à votre compte. Échapper, c'est imprimer chaque lettre dans un encadré de citation bien visible, pour qu'aucune ne passe pour un avis de la rédaction.
Concepts Clés et Termes
- Cross-site scripting (CWE-79)
- Une page web inclut des données non fiables sans les neutraliser pour le navigateur : le balisage ou le script qu'elles contiennent est analysé et exécuté dans l'origine de la page, avec accès à son DOM, à ses cookies et à ses API.
- Reflected, stored and DOM-based XSS
- Le XSS réfléchi renvoie directement des données de la requête dans la réponse, en général via un lien piégé. Le XSS stocké enregistre la valeur et la sert à chaque visiteur. Le XSS basé sur le DOM ne passe même pas par le serveur : le JavaScript côté client copie des données de l'URL ou du stockage vers un sink comme
innerHTML. - Contextual output encoding
- Chaque contexte de sortie exige son propre encodage : entités HTML pour le texte d'élément et les attributs cités, échappement de chaîne JavaScript dans les scripts, encodage en pourcentage dans les paramètres d'URL, et vérification du schéma pour
hrefetsrc. Encoder en HTML une valeur placée dans un script ne suffit pas. - Sanitizing vs encoding
- Encoder affiche le balisage comme du texte. Quand les utilisateurs doivent envoyer de la mise en forme, faites passer le HTML par un assainisseur à liste autorisée (DOMPurify, nh3 qui succède à bleach, OWASP Java HTML Sanitizer, HtmlSanitizer, ammonia) qui garde les balises permises et retire scripts, gestionnaires d'événements et URL
javascript:. - Content Security Policy (CSP)
- Un en-tête de réponse qui indique au navigateur quels scripts peuvent s'exécuter. Un
script-srcà nonce et sans'unsafe-inline'bloque la plupart des scripts injectés même si un bug d'encodage passe, etrequire-trusted-types-for 'script'verrouille les sinks du DOM.
Déroulement de l'Attaque Étape par Étape
Un texte non fiable atteint une page
Un terme de recherche, un champ de profil, un commentaire, un fragment d'URL ou une réponse d'API est inclus lors de la construction de la page côté serveur ou de sa mise à jour dans le navigateur.
Il est écrit sans le bon encodage
L'échappement du gabarit est désactivé, la valeur arrive dans un contexte script ou URL que l'échappement HTML ne couvre pas, ou le code client l'affecte à innerHTML. La valeur de test inoffensive <img src=x onerror=alert(1)> survit intacte.
Le navigateur l'interprète comme du code
Le navigateur de la victime construit un vrai élément <img> et déclenche onerror, ou exécute un lien javascript: au clic.
Le script agit au nom du site
Il s'exécute avec l'origine du site : il peut lire la page, appeler les API du site avec les cookies ou jetons de la victime, modifier ce que voit l'utilisateur et soumettre des formulaires à sa place.
Guides sur le XSS par langage
Liste de Contrôle de Sécurité pour l'Ingénierie
- Rendez chaque page via un moteur de gabarits à échappement automatique activé, et relisez chaque exception (
|safe,Html.Raw,dangerouslySetInnerHTML,raw,unsafe { },{!! !!}). - Encodez pour le contexte exact : texte HTML et attributs cités, chaînes JavaScript, paramètres d'URL ; ne construisez jamais de HTML ou de JavaScript par concaténation de chaînes.
- Assainissez le HTML fourni par les utilisateurs avec un assainisseur à liste autorisée maintenu, au moment où il est rendu.
- N'autorisez que
httpethttpsdans les URL fournies par les utilisateurs avant qu'elles n'atteignenthref,srcou une navigation. - Envoyez une Content-Security-Policy à nonce, sans
'unsafe-inline', ainsi queX-Content-Type-Options: nosniff. - Gardez les jetons de session dans des cookies
HttpOnly,SecureetSameSite=Laxplutôt que danslocalStorage.