Comprendre le mécanisme
Une XSS apparaît lorsqu’une donnée non fiable est interprétée comme du code dans un contexte de navigateur. Un encodage HTML ne sécurise pas automatiquement une chaîne placée dans JavaScript, une URL ou une feuille de style. La bonne défense commence par éviter les destinations interprétatives inutiles, puis par employer un mécanisme de rendu et une validation adaptés au contexte. La validation d’entrée seule n’exprime pas tous ces contextes de sortie.
Raisonner et vérifier
Pour afficher du texte dans le DOM, textContent préserve son rôle de donnée, contrairement à une insertion HTML libre. Les URL exigent aussi un contrôle de schéma et de destination selon le besoin. Les templates à échappement automatique réduisent le risque tant que leurs sorties sûres ne sont pas abusivement désactivées. Testez les chemins de rendu initiaux et les mises à jour dynamiques, y compris le corrigé et les exports affichés.
Contexte de sortie
L’échappement dépend du contexte de sortie. Chaque contexte a sa syntaxe et ses risques. Le texte HTML, un attribut, une URL et JavaScript ont des règles distinctes. Évitez de réutiliser une chaîne déjà encodée dans un autre contexte sans définir la protection réellement attendue.
Erreur fréquente à comprendre
Un échappement HTML est universel pour JavaScript et URL.
Chaque contexte a sa syntaxe et ses risques.
Texte DOM
textContent traite une chaîne comme du texte. Cette API évite le parsing HTML de cette valeur. textContent place la valeur comme texte sans parser les balises qu’elle contient. C’est adapté à un libellé ; testez le DOM pour vérifier que des chevrons restent visibles et ne créent pas un élément actif.
Erreur fréquente à comprendre
textContent interprète la chaîne comme du HTML actif.
Cette API évite le parsing HTML de cette valeur.
HTML interprété
innerHTML peut être un point d’injection. Cette API demande une politique de contenu adaptée. innerHTML demande au navigateur d’interpréter du balisage. Une donnée non fiable à cette destination exige une politique adaptée ; remplacer des caractères au hasard ne constitue pas une sanitisation complète.
Erreur fréquente à comprendre
innerHTML est sûr pour toute entrée utilisateur.
Cette API demande une politique de contenu adaptée.
CSP complémentaire
Une CSP complète les défenses d’injection. Elle ne corrige pas automatiquement les points d’injection. Une politique CSP peut limiter certaines exécutions ou ressources, mais n’efface pas toutes les conséquences d’une injection. Gardez la séparation données/code et l’encodage adapté comme protections de base.
Erreur fréquente à comprendre
Une CSP remplace toute validation de sortie.
Elle ne corrige pas automatiquement les points d’injection.
Capacités d’origine
Une XSS peut agir sous l’origine compromise. La frontière d’origine ne distingue pas ce script hostile. Une XSS peut lire des données accessibles et agir sous l’origine de la page. Le risque dépasse le seul vol de cookie : actions, accès API et modification d’interface peuvent rester possibles.
Erreur fréquente à comprendre
La SOP neutralise tout script de même origine.
La frontière d’origine ne distingue pas ce script hostile.
HttpOnly limité
HttpOnly limite la lecture du cookie. Le script peut encore déclencher des actions. Même sans lire la valeur du cookie, un script peut envoyer des demandes authentifiées depuis la page. Cet attribut reste utile mais ne rend pas acceptable un point d’injection HTML.
Erreur fréquente à comprendre
HttpOnly supprime toute conséquence d’une XSS.
Le script peut encore déclencher des actions.
Schémas URL
Une URL doit suivre une politique de schémas admis. Le contexte URL demande aussi un contrôle de destination et de schéma. Un attribut href échappé peut encore porter un schéma dangereux ou une destination interdite. Parsez et admettez les schémas et hôtes selon le besoin avant de rendre le lien.
Erreur fréquente à comprendre
Échapper une URL suffit à rendre tout schéma acceptable.
Le contexte URL demande aussi un contrôle de destination et de schéma.
HTML autorisé
Un HTML autorisé demande une sanitisation adaptée. Le stockage ne rend pas sûre une entrée hostile. Si le produit exige du HTML utilisateur, employez un nettoyage maintenu avec une liste d’éléments et attributs admis. Vérifiez le résultat dans le contexte final plutôt qu’un simple retrait de script.
Erreur fréquente à comprendre
Tout HTML stocké en base est automatiquement fiable.
Le stockage ne rend pas sûre une entrée hostile.
Rendu effectif
Les tests doivent vérifier le rendu effectif. L’interprétation par le navigateur détermine le comportement. Des tests sur la chaîne serveur peuvent manquer une interprétation du navigateur. Contrôlez éléments, attributs et comportement dans le DOM avec données factices contenant guillemets, chevrons et URL non admise.
Erreur fréquente à comprendre
Une chaîne présente dans le code suffit à prouver une exécution.
L’interprétation par le navigateur détermine le comportement.
Données et code
Les données et le code doivent être séparés. La construction de code avec des données non fiables crée un risque. Préférez des API structurées et des valeurs passées comme données. Construire du JavaScript ou des handlers HTML par concaténation multiplie les contextes d’échappement et rend la preuve de sécurité fragile.
Erreur fréquente à comprendre
Concaténer des entrées dans du JavaScript est toujours sûr.
La construction de code avec des données non fiables crée un risque.
Atelier guidé : lire, expliquer et vérifier le code
const value = '<img src=x onerror=alert(1)>';
const label = document.createElement('div');
label.textContent = value; La valeur ressemble à une balise avec un gestionnaire, mais textContent la conserve comme texte. Le navigateur ne doit donc pas créer l’image active de cette chaîne dans ce div. Inspectez le DOM puis comparez avec un laboratoire isolé de parsing HTML, sans utiliser de données réelles.
Le contrôle est local à cette affectation. Cette API ne parse pas la valeur comme du HTML. Ce serait une autre sémantique de sink HTML. La création de texte ne réalise pas cet appel.
Travail pratique : Affichez une note de laboratoire contenant des chevrons, guillemets et caractères Unicode dans le rendu initial puis dans une mise à jour DOM.
Critères de correction : Vérifiez le texte attendu et l’absence de nouveaux éléments ou gestionnaires d’événements interprétés. Inspectez chaque destination de données ; remplacez les insertions HTML inutiles et testez séparément les URL permises.
Libellé DOM : conserver le texte comme texte
Le besoin fonctionnel est d’afficher un libellé, donc aucune balise n’a besoin d’être interprétée. innerHTML donne pourtant au navigateur un contexte de parsing HTML. Une valeur reçue peut alors créer des éléments et attributs actifs au lieu de rester une simple chaîne visible.
Affectez la valeur à textContent sur l’élément prévu. Une chaîne contenant des chevrons ou des guillemets s’affiche alors comme texte, sans devenir le balisage décrit par ces caractères. Ne pré-encodez pas arbitrairement une valeur avant textContent, au risque d’afficher des entités littérales ou de mélanger les contrats.
Testez le DOM obtenu : texte exact et absence d’élément enfant provenant de la valeur. Si un autre produit exige du HTML enrichi, il doit disposer d’un parcours différent avec nettoyage maintenu et politique précise. CSP et HttpOnly restent utiles mais ne remplacent pas le bon choix de destination pour ce libellé.
Points de vigilance : textContent insère du texte, sans analyser des balises ni des attributs événementiels. Une liste noire partielle manque d’autres constructions et contextes dangereux. HttpOnly limite la lecture d’un cookie, pas les actions qu’un script injecté peut effectuer. Un encodage URL n’est pas le contrat d’insertion du texte dans le DOM.
Documentation de référence ↗Exemple commenté
const title = document.querySelector("[data-lab-title]");
title.textContent = userSuppliedLabel;userSuppliedLabel reste ici du texte dans cet élément. Cet exemple n’autorise pas à placer la même valeur librement dans une URL ou du JavaScript.
Exercice de mise en pratique
Affichez une note de laboratoire contenant des chevrons, guillemets et caractères Unicode dans le rendu initial puis dans une mise à jour DOM.
Voir une proposition de correction
Vérifiez le texte attendu et l’absence de nouveaux éléments ou gestionnaires d’événements interprétés. Inspectez chaque destination de données ; remplacez les insertions HTML inutiles et testez séparément les URL permises.
Points de vérification
- Identifier la destination exacte.
- Préférer les API de texte.
- Ne pas désactiver l’échappement pour corriger la mise en page.
Contrôle de connaissances
Cours associé : 20. XSS : données, code et contexte de sortie ↗Validation du module
101 questions, objectif pédagogique de 75 %. Durée conseillée de 150 minutes, sans limite imposée. Les questions et les choix sont mélangés ; le corrigé apparaît après validation. Le contrôle rapide de la leçon et l’examen final du cours restent des exercices distincts.
Commencer ou reprendre les 101 questions →Cette marque suit votre propre avancement ; elle ne certifie pas la maîtrise du sujet. Effectuez l’exercice avant de passer à la suite.
