La CSP est l'une des défenses les plus efficaces contre les attaques XSS, mais aussi l'une des plus mal comprises — une politique trop stricte casse le site, une politique trop permissive ne protège rien. Ce guide explique comment trouver le bon équilibre.
La Content-Security-Policy fonctionne sur le principe d'une liste blanche : plutôt que d'essayer de bloquer les contenus malveillants connus (liste noire, toujours incomplète), elle définit précisément quelles sources sont autorisées à fournir chaque type de ressource (scripts, styles, images, polices...). Tout ce qui n'est pas explicitement autorisé est bloqué par le navigateur, qu'il s'agisse d'un script légitime oublié ou d'un script injecté par un attaquant.
| Directive | Rôle |
|---|---|
default-src | Valeur de repli pour toute ressource sans directive spécifique. |
script-src | La plus critique en sécurité — contrôle quels scripts peuvent s'exécuter. |
frame-ancestors | Protection anti-clickjacking, remplace X-Frame-Options. |
object-src 'none' | Recommandé presque systématiquement — les plugins (Flash et consorts) sont obsolètes et risqués. |
base-uri 'self' | Empêche une injection de modifier la balise <base> pour rediriger les chemins relatifs. |
unsafe-inline autorise l'exécution de scripts écrits directement dans l'attribut onclick ou entre des balises <script> sans source externe — exactement la technique la plus utilisée par les attaques XSS. L'activer revient à neutraliser une grande partie de la protection de la directive script-src.
unsafe-evalautorise l'utilisation deeval()et fonctions similaires qui exécutent du texte comme du code — un vecteur d'attaque tout aussi dangereux si une entrée utilisateur atteint un jour ce code, même indirectement.
Si une application existante dépend fortement de scripts inline, la migration vers une CSP stricte demande un travail de refactoring (déplacer le JavaScript inline vers des fichiers externes) — un coût ponctuel pour un gain de sécurité durable.
L'en-tête Content-Security-Policy-Report-Only applique exactement la même syntaxe que la CSP normale, mais ne bloque rien : il se contente de journaliser (ou d'envoyer à une URL de rapport via report-uri) ce qui aurait été bloqué. C'est la méthode recommandée pour déployer une nouvelle CSP sur un site existant sans risquer de casser une fonctionnalité en production.
Pour les sites qui ont réellement besoin de scripts inline (générés dynamiquement côté serveur), la CSP propose deux alternatives plus sûres qu'unsafe-inline :
nonce du script autorisé. Un script injecté par un attaquant ne connaîtra jamais le nonce courant.Non — la CSP est une protection en profondeur supplémentaire, pas un substitut. Échapper correctement les sorties HTML et valider les entrées reste la défense de première ligne contre les failles d'injection.
Techniquement oui, mais les navigateurs appliquent alors l'intersection la plus restrictive de toutes les politiques — généralement source de confusion plutôt que de bénéfice ; une seule politique bien pensée est préférable.
Presque, mais pas totalement — certaines directives comme frame-ancestors ou report-uri ne fonctionnent pas (ou pas correctement) via la balise meta et nécessitent l'en-tête HTTP.
La console JavaScript du navigateur affiche un message explicite "Refused to load/execute..." pour chaque violation, indiquant la ressource et la directive concernée — le point de départ pour ajuster la politique.
Outils similaires