Identifiez les vecteurs XSS propres au balisage et déployez les défenses natives du HTML : sandbox, noopener et Content Security Policy.
Ouvrir cette leçon dans KodokonLe contexte d'échappement fait toute la différence : une valeur inoffensive dans un nœud texte devient exécutable dans un attribut. L'attribut non quoté est le pire des cas : une simple espace dans la donnée injectée suffit à créer un nouvel attribut, par exemple un gestionnaire onmouseover. Même correctement quotée, une valeur reste dangereuse dans les sinks sensibles : href et src acceptent le schéma javascript:, formaction détourne la soumission d'un formulaire, et srcdoc interprète comme du HTML ses entités une fois décodées.
<!-- userName = x onmouseover=alert(1) -->
<img src="avatar.png" alt=x onmouseover=alert(1)>
<!-- L'attribut non quoté laisse entrer un handler -->L'attribut sandbox d'une iframe retire tous les privilèges, puis vous en réaccordez à la carte : allow-scripts, allow-forms, allow-popups... Sans allow-same-origin, le document embarqué reçoit une origine opaque : pas de cookies, pas de storage, aucun accès au DOM parent - même s'il est servi depuis votre propre domaine.
<iframe
src="https://widget.example.com"
sandbox="allow-scripts allow-forms"
referrerpolicy="no-referrer">
</iframe>Un lien target=_blank donnait historiquement à la page ouverte une référence window.opener vers votre onglet : elle pouvait rediriger votre page vers un clone de phishing, l'attaque dite de tabnabbing. Les navigateurs modernes appliquent désormais noopener implicitement sur target=_blank, mais l'expliciter reste indispensable pour window.open en JavaScript et pour documenter l'intention ; ajoutez noreferrer pour supprimer aussi l'en-tête Referer.
<a href="https://external.example"
target="_blank"
rel="noopener noreferrer">
Consulter la ressource externe
</a>Une Content Security Policy limite les sources de code exécutable et neutralise la plupart des XSS, même lorsque l'injection a réussi. Déclarée via une balise <meta http-equiv>, elle comporte toutefois des angles morts : les directives frame-ancestors, report-uri et sandbox y sont ignorées et exigent l'en-tête HTTP. Préférez les nonces régénérés à chaque réponse aux listes de domaines, que la directive strict-dynamic rend d'ailleurs obsolètes.
<meta http-equiv="Content-Security-Policy"
content="default-src 'self';
script-src 'self' 'nonce-r4nd0m'">allow-scripts et allow-same-origin sur une iframe de même origine annule-t-il le sandbox ?rel=noopener protège-t-il ?window.opener pour rediriger votre onglet vers un site de phishing<meta http-equiv> ?