Une seule faille XSS suffit à compromettre l’ensemble d’un site. La Content Security Policy est le mécanisme HTTP qui vous permet de l’empêcher – à condition de la configurer correctement. Ce guide vous donne la méthode complète : définition, directives essentielles, déploiement progressif, erreurs fréquentes et bonnes pratiques actuelles.
Qu’est-ce que la CSP (Content Security Policy) ?
La Content Security Policy est un en-tête HTTP de sécurité que votre serveur envoie au navigateur. Il lui indique précisément quelles ressources il est autorisé à charger : scripts, styles, images, polices, connexions réseau, iframes.
En l’absence de CSP, le navigateur accepte par défaut tout ce que la page lui demande de charger, quelle qu’en soit l’origine. C’est cette permissivité que les attaques XSS exploitent.
Principe fondamental : la CSP ne corrige pas les failles de votre code. Elle réduit drastiquement l’impact d’une exploitation réussie en empêchant le navigateur d’exécuter des ressources non autorisées.
À quoi sert une Content Security Policy concrètement ?
La CSP protège contre trois catégories de menaces principales :
- Les attaques XSS (Cross-Site Scripting) : injection de scripts malveillants dans vos pages.
- Le chargement de ressources non autorisées : scripts tiers injectés, pixels de tracking inconnus, iframes frauduleuses.
- Le clickjacking et l’injection de contenu : affichage de votre site dans un contexte contrôlé par un attaquant.
Sans CSP, même un code applicatif propre reste exposé si une dépendance tierce est compromise. Avec une politique bien configurée, le navigateur refuse d’exécuter toute ressource qui ne figure pas dans votre liste blanche – même si elle est injectée dans le DOM.
Les directives CSP essentielles à connaître
La CSP fonctionne par directives. Chaque directive contrôle un type de ressource précis. Voici celles que vous utiliserez dans la quasi-totalité des projets.
Les directives de base
| Directive | Ressources contrôlées |
|---|---|
| `default-src` | Valeur de repli pour toutes les directives non définies |
| `script-src` | Scripts JavaScript |
| `style-src` | Feuilles de style CSS |
| `img-src` | Images |
| `font-src` | Polices de caractères |
| `connect-src` | Requêtes XHR, Fetch, WebSocket |
| `frame-src` | Iframes et frames |
| `object-src` | Plugins (Flash, etc.) |
| `base-uri` | Valeur de la balise `<base>` |
| `form-action` | Destinations des formulaires |
Les valeurs de source les plus utilisées
- `’self’` : autorise uniquement les ressources du même domaine.
- `’none’` : bloque tout, sans exception.
- `’unsafe-inline’` : autorise les scripts et styles inline (à éviter absolument).
- `’unsafe-eval’` : autorise `eval()` et fonctions équivalentes (à éviter).
- `https://cdn.exemple.com` : autorise un domaine externe précis.
- `’nonce-xxxx’` : autorise un script inline spécifique via un jeton unique par requête.
- `’sha256-xxxx’` : autorise un script inline dont le hash correspond.
Quelle différence entre `Content-Security-Policy` et `Content-Security-Policy-Report-Only` ?
C’est la distinction la plus importante pour un déploiement sans régression. `Content-Security-Policy` applique la politique en mode enforcement : le navigateur bloque activement toute ressource non autorisée. Une mauvaise configuration peut casser votre site en production. `Content-Security-Policy-Report-Only` observe sans bloquer : le navigateur signale les violations dans la console et vers l’URL de rapport que vous définissez, mais laisse passer toutes les ressources. C’est le mode à utiliser pendant la phase d’audit.
La stratégie recommandée : commencez toujours en `Report-Only`, analysez les violations pendant une à deux semaines, affinez votre politique, puis basculez en enforcement.
Comment déployer une CSP en 2026 : méthode progressive
Un déploiement brutal en enforcement est la cause numéro un des régressions. Voici la méthode en quatre étapes.
Étape 1 – Audit en mode report-only
Ajoutez cet en-tête à votre serveur :
« ` Content-Security-Policy-Report-Only: default-src ‘self’; report-uri /csp-violations « `
Naviguez sur l’ensemble de votre site et collectez les violations. Chaque violation vous indique une ressource que votre politique future devra autoriser ou que vous devrez supprimer.
Étape 2 – Inventaire des ressources légitimes
Listez toutes les origines que votre site charge réellement :
- domaines CDN (scripts, polices, styles),
- outils analytics et tag managers,
- APIs et endpoints Fetch/XHR,
- services de paiement ou de chat,
- iframes tierces (vidéos, cartes).
Étape 3 – Rédaction de la politique
Construisez votre politique directive par directive, en partant du principe du moindre privilège : n’autorisez que ce qui est strictement nécessaire.
Exemple de politique de base pour un site avec Google Analytics et une police Google Fonts :
« ` Content-Security-Policy: default-src ‘self’; script-src ‘self’ https://www.googletagmanager.com ‘nonce-{RANDOM}’; style-src ‘self’ https://fonts.googleapis.com; font-src ‘self’ https://fonts.gstatic.com; img-src ‘self’ data: https://www.google-analytics.com; connect-src ‘self’ https://www.google-analytics.com; frame-src ‘none’; object-src ‘none’; base-uri ‘self’; form-action ‘self’; « `
Étape 4 – Bascule en enforcement et monitoring continu
Une fois la politique stabilisée, remplacez `Report-Only` par `Content-Security-Policy`. Conservez la directive `report-uri` ou `report-to` pour continuer à recevoir les violations en production.
Gérer les scripts inline et les frameworks modernes
C’est le point de friction le plus courant. Les frameworks JavaScript modernes (React, Next.js, Vue, Angular) génèrent souvent des scripts inline ou utilisent des mécanismes d’hydratation qui entrent en conflit avec une CSP stricte. Deux approches propres pour gérer les scripts inline :
- Le nonce : votre serveur génère un jeton aléatoire à chaque requête et l’injecte dans l’en-tête CSP et dans l’attribut `nonce` de chaque balise `<script>` légitime. C’est la méthode recommandée pour les applications dynamiques.
- Le hash : vous calculez le hash SHA-256 du contenu exact du script inline et vous l’ajoutez à `script-src`. Adapté aux scripts statiques qui ne changent jamais.
À ne jamais faire : ajouter `’unsafe-inline’` pour « débloquer » rapidement une situation. Cela annule l’essentiel de la protection XSS que la CSP est censée apporter.
CSP et outils tiers : analytics, tag managers, CDN
La réalité des sites modernes, c’est une accumulation de scripts tiers. Chaque outil marketing, chaque pixel de tracking, chaque widget de chat représente une origine à déclarer.
Quelques règles pratiques :
- Google Tag Manager charge lui-même d’autres scripts dynamiquement. Une CSP stricte peut bloquer des tags injectés via GTM. Préférez charger les scripts directement plutôt que via un tag manager si la sécurité est prioritaire.
- Les CDN : autorisez uniquement les sous-domaines précis que vous utilisez, pas un wildcard `*.cdn.com` qui ouvre la porte à tous les sous-domaines du CDN.
- Les APIs tierces : déclarez leurs endpoints dans `connect-src`, pas dans `script-src`.
Comment tester et déboguer une CSP
Trois outils à utiliser systématiquement :
- La console du navigateur : les violations CSP apparaissent en rouge avec le détail de la directive violée et de la ressource bloquée.
- [CSP Evaluator de Google](https://csp-evaluator.withgoogle.com/) : analyse votre politique et identifie les faiblesses (wildcards trop larges, `unsafe-inline`, etc.).
- L’endpoint `report-uri` : collectez les violations en production sur un endpoint dédié ou via un service comme `report-uri.com`.
Lors du débogage, lisez toujours le message d’erreur complet. Il indique précisément quelle directive a bloqué quelle ressource, ce qui vous permet d’ajuster chirurgicalement votre politique.
Les erreurs les plus fréquentes en configuration CSP
Utiliser `’unsafe-inline’` ou `’unsafe-eval’`
Ces deux valeurs sont des portes ouvertes. Si votre politique les contient dans `script-src`, vous neutralisez la protection contre XSS. Remplacez-les par des nonces ou des hashes.
Oublier `object-src` et `base-uri`
`object-src ‘none’` empêche le chargement de plugins (Flash, Java) qui peuvent contourner les autres directives. `base-uri ‘self’` empêche un attaquant de redéfinir l’URL de base de vos liens relatifs.
Utiliser des wildcards trop larges
`script-src *` ou `script-src https:` autorisent n’importe quel script depuis n’importe quel domaine HTTPS. C’est presque aussi permissif qu’une absence de CSP.
Déployer directement en enforcement
Sans phase `Report-Only`, vous risquez de bloquer des ressources légitimes et de casser des fonctionnalités en production. La phase d’observation n’est pas optionnelle.
Bonnes pratiques CSP pour 2026
La philosophie a évolué : une CSP efficace aujourd’hui n’est pas une liste blanche exhaustive de domaines, c’est une politique basée sur les nonces ou les hashes, complétée par un monitoring continu.
Les principes à retenir :
- Commencez strict : `default-src ‘none’` et ajoutez uniquement ce dont vous avez besoin.
- Préférez les nonces aux domaines pour les scripts : un nonce par requête est infiniment plus sûr qu’un domaine entier en liste blanche.
- Réduisez votre surface d’attaque : chaque script tiers supprimé est une directive en moins à gérer.
- Automatisez le monitoring : les violations en production doivent générer des alertes, pas juste des logs.
- Révisez votre politique régulièrement : à chaque ajout d’un outil tiers, mettez à jour votre CSP en passant d’abord par `Report-Only`.
- Combinez la CSP avec les autres headers : `Strict-Transport-Security`, `X-Frame-Options`, `Referrer-Policy` et `Permissions-Policy` forment un ensemble cohérent.
Passez à l’action : votre première CSP en moins d’une heure
Vous avez maintenant la méthode complète. L’étape suivante est concrète : ajoutez dès aujourd’hui l’en-tête `Content-Security-Policy-Report-Only: default-src ‘self’; report-uri /csp-violations` à votre serveur.
Naviguez sur votre site pendant quelques jours, analysez les violations, construisez votre politique réelle – puis basculez en enforcement. Une CSP imparfaite déployée progressivement vaut infiniment mieux qu’une politique parfaite jamais mise en production.
FAQ
La CSP (Content Security Policy) est un en-tête HTTP qui indique au navigateur quelles ressources il est autorisé à charger sur une page. Elle constitue la principale défense côté navigateur contre les attaques XSS et l’injection de contenu non autorisé.
Non. La CSP est une couche de défense supplémentaire, pas un substitut à la validation des entrées et à l’encodage des sorties côté serveur. Une application vulnérable au XSS reste vulnérable même avec une CSP : la politique limite seulement l’impact de l’exploitation.
Tous les navigateurs modernes supportent la CSP niveau 2 et la grande majorité supportent le niveau 3. La compatibilité n’est plus un frein au déploiement. Seuls les navigateurs très anciens ou les environnements embarqués spécifiques peuvent poser problème.
Utilisez systématiquement `Content-Security-Policy-Report-Only` avant tout déploiement en enforcement. Cette phase d’observation vous permet d’identifier toutes les ressources légitimes à autoriser sans jamais bloquer quoi que ce soit en production.
Un `nonce` est un jeton aléatoire généré côté serveur à chaque requête HTTP et injecté dans l’en-tête CSP et dans l’attribut `nonce` des scripts autorisés. Un `hash` est l’empreinte cryptographique du contenu exact d’un script inline. Le nonce convient aux applications dynamiques, le hash aux scripts statiques dont le contenu ne change jamais.