Se protéger : échappement, CSP, sanitisation
11 min · Débutant · 7 août 2026
Première ligne de défense : l’échappement contextuel
La protection de fond contre toutes les familles de XSS vues dans ce cours consiste à échapper toute donnée non fiable avant de l’insérer dans une page : remplacer les caractères qui ont un sens spécial en HTML par leur équivalent inoffensif.
< devient <
> devient >
" devient "
' devient '
& devient & Une fois échappée, une charge comme <img src=x onerror=...> s’affiche comme du texte littéral, jamais comme une balise active. Le détail qui compte : le contexte d’insertion change les règles. Échapper pour un contexte HTML ne protège pas un contexte JavaScript ou un attribut d’URL, qui ont chacun leurs propres caractères sensibles.
Préférer textContent à innerHTML
Le réflexe le plus direct, quand aucun HTML n’a besoin d’être inséré : ne jamais utiliser innerHTML pour du texte simple. textContent ne réalise strictement aucune interprétation HTML, quel que soit son contenu.
<!-- HTML -->
<input type="text" id="champ" placeholder="Tape ici..." style="width:100%;box-sizing:border-box;padding:6px;" />
<div id="resultat" style="margin-top:10px;"></div>
// JS
document.getElementById('champ').addEventListener('input', function (e) {
// Correction : textContent insere du texte brut, jamais interprete comme du HTML
document.getElementById('resultat').textContent = e.target.value;
}); Tape exactement la même charge qu’au chapitre sur la XSS DOM-based (<img src=x onerror="console.log('XSS DOM executee')">) : elle s’affiche cette fois telle quelle, comme texte visible, sans jamais s’exécuter.
Astuce
Ce bac à sable utilise le même code HTML que celui du chapitre sur la XSS DOM-based, avec une seule ligne modifiée (textContent au lieu de innerHTML). C’est souvent tout ce qu’il faut corriger, une fois le sink dangereux identifié.
Deuxième ligne de défense : une CSP stricte
Le cours sur HTTP a introduit l’en-tête Content-Security-Policy. Appliquée à la XSS, une CSP stricte (sans la directive 'unsafe-inline') empêche l’exécution de tout script ou gestionnaire d’évènement inline, y compris <script>...</script> et onerror="...", exactement les techniques utilisées dans les démonstrations de ce cours.
Info
Une CSP correctement configurée aurait bloqué chacune des démonstrations de ce cours, malgré l’absence d’échappement. C’est pour ça qu’elle est présentée comme une seconde ligne de défense : elle limite les dégâts d’une erreur d’échappement, elle ne dispense jamais de corriger cette erreur.
Troisième cas : quand du HTML doit vraiment être autorisé
Un champ de commentaire qui autorise du gras ou de l’italique ne peut pas se contenter d’échapper tout le HTML : il doit sanitiser, c’est-à-dire ne conserver qu’une liste explicite de balises et d’attributs jugés sûrs (une allowlist), et rejeter tout le reste. Écrire soi-même une liste de balises à bloquer est une erreur classique : la liste est presque toujours incomplète, exactement comme pour la validation d’entrée contre les injections SQL. Utiliser une bibliothèque de sanitisation éprouvée reste la seule approche fiable dans ce cas.