Content Security Policy (CSP)
Dire au navigateur quels scripts ont le droit de tourner : nonces, hashes, strict-dynamic. Une défense en profondeur — l'échappement reste la première protection.
Le principe : liste blanche déclarative
Le serveur envoie un en-tête qui dit au navigateur d'où chaque type de ressource peut venir : scripts, styles, images, frames, formulaires. Tout le reste est bloqué — y compris un script injecté par XSS.
Retenez l'ordre : la CSP ne remplace pas l'échappement de sortie, c'est une seconde barrière qui limite les dégâts quand une injection passe quand même.
Content-Security-Policy:
default-src 'self';
script-src 'nonce-r4nd0m' 'strict-dynamic';
object-src 'none';
base-uri 'self'; form-action 'self'Nonces, hashes et strict-dynamic
- Nonce : un jeton aléatoire unique par page, recopié sur chaque
<script nonce="…">légitime. Un script injecté n'a pas le bon nonce → bloqué. - Hash : autorise un script inline précis par son empreinte (pratique pour un snippet figé).
- 'strict-dynamic' : fait confiance aux scripts chargés par un script autorisé — très utile avec les bundlers modernes. Notez que les navigateurs compatibles ignorent alors 'self' et les listes de domaines dans
script-src.
Ci-dessus, 'nonce-r4nd0m' est un exemple : en production, nonce aléatoire d'au moins 128 bits, régénéré à chaque réponse.
script-src 'self' seul n'est pas une CSP stricte : si l'attaquant peut faire héberger un fichier JS sur votre domaine (upload, JSONP, bibliothèque compromise), le navigateur l'exécute.Déployer sans tout casser
- Commencez en Content-Security-Policy-Report-Only : les violations sont signalées, rien n'est bloqué.
- Collectez les rapports (
report-uri, remplacé progressivement parreport-to: mentionnez les deux pendant la transition), corrigez, puis basculez en mode blocage. - Bannissez
'unsafe-inline'et'unsafe-eval': ils annulent l'essentiel de la protection.