Expliquez le XSS stocké, réfléchi et basé sur le DOM.
Réponse courte
Tout XSS injecte un script contrôlé par l'attaquant dans le navigateur d'une victime. Le XSS stocké persiste la charge utile sur le serveur (par exemple un commentaire) et touche tous ceux qui la consultent ; le XSS réfléchi renvoie la charge utile depuis le serveur dans une seule réponse, généralement via un lien forgé ; le XSS basé sur le DOM n'atteint jamais la logique serveur — du JavaScript côté client vulnérable écrit une entrée non fiable dans la page.
Le cross-site scripting (XSS) est la classe de bugs où un attaquant fait exécuter son JavaScript dans la session de navigateur d'un autre utilisateur, à l'intérieur de l'origine de confiance de votre site. Une fois cela fait, le script peut lire les cookies, le DOM et les jetons, effectuer des requêtes authentifiées et usurper l'identité de la victime. Les trois variantes diffèrent par l'endroit où vit la charge utile et comment elle parvient à s'exécuter — et cette différence guide à la fois la détection et le correctif.
Stocké (persistant)
La charge utile est enregistrée sur le serveur — dans une base de données, un champ de commentaire, un nom de profil — et renvoyée à chaque utilisateur qui charge ce contenu. C'est la forme la plus dangereuse car elle ne nécessite aucune interaction par victime et peut se propager comme un ver. Un seul <script> injecté dans un message de forum peut toucher des milliers de sessions.
Réfléchi (non persistant)
La charge utile est incluse dans une requête (un paramètre de requête, un champ de formulaire) et immédiatement renvoyée dans la réponse sans être stockée. L'attaquant doit attirer chaque victime à cliquer sur un lien forgé ou à soumettre un formulaire malveillant. C'est à coup unique par victime, mais dévastateur en hameçonnage.
Basé sur le DOM
Ici, le serveur peut être entièrement innocent. Du JavaScript côté client vulnérable lit une entrée contrôlable par l'attaquant (comme location.hash) et l'écrit dans un puits dangereux tel que innerHTML, document.write ou eval. La charge utile peut n'apparaître dans aucun corps de requête HTTP que le serveur traite, c'est pourquoi les WAF et journaux côté serveur peuvent la manquer. Le script injecté lui-même provient des mêmes familles de payloads XSS, quelle que soit la façon dont il atteint le puits.
Pourquoi la distinction importe
Le stocké et le réfléchi sont largement atténués par un encodage de sortie contextuel sur le serveur et une Content-Security-Policy forte. Le XSS DOM doit être corrigé dans le code client — en utilisant des API sûres comme textContent et setAttribute au lieu d'innerHTML.
Les recruteurs recherchent le cadrage où/comment, la mention d'un puits concret pour le XSS DOM, et la conscience que le XSS stocké est généralement la priorité la plus haute en raison de son rayon d'impact.
Questions de suivi probables
- Pourquoi le XSS basé sur le DOM est-il parfois invisible pour un WAF côté serveur ?
- Quels puits (innerHTML, document.write) rendent le XSS DOM possible ?
- Comment prioriseriez-vous la correction du XSS stocké vs réfléchi ?