Politique de sécurité du contenu : configuration CSP, risques de contournement et déploiement

La CSP (Content Security Policy) est un en-tête de réponse qui indique au navigateur quels scripts peuvent s'exécuter et quels domaines peuvent charger des ressources. Le déploiement se fait en trois étapes : d'abord Report-Only pendant 14 jours pour collecter les sources de violation, puis affiner la liste blanche,

CSP部署:报告模式先跑两周再切强制CSP: report-only for two weeks, then enforce 一上来就enforce会把站内第三方脚本全打挂Enforcing on day one breaks every third-party script 1 Report-Only1 Report-Only 只收集违规 不拦截Collect violations, no block 跑14天 收集所有来源Run 14 days to collect sources 2 白名单收敛2 Whitelist tuning 按报告加域名 不violent-inlineAdd domains from reports sha256 hash 替代unsafe-inlinesha256 instead of unsafe-inline 3 Enforce3 Enforce 违规日志为0再切Switch when reports hit 0 保留report-uri 继续监控Keep report-uri watching 核心指令Core directives default-src 兜底 script-src 控脚本default-src fallback, script-src controls JS object-src ‘none’ frame-ancestors 防嵌套object-src none, frame-ancestors 红线Red lines 别开 * 通配符 等于没配Wildcard * equals no CSP unsafe-inline 留着等于被绕过unsafe-inline defeats the purpose 判定:报告模式跑满14天且违规数降到个位数,再切EnforceDecision: enforce after 14 days of near-zero reports 反直觉:CSP不是越严越安全,配错了比不配更危险Counterintuitive: misconfigured CSP is worse than none 先报告后强制,把违规源一个个收进白名单Report first, enforce later
Déploiement CSP en trois étapes : collecte en Report-Only, affinage de la liste blanche, passage en Enforce

Politique de sécurité du contenu : configuration CSP, risques de contournement et déploiement

Conclusion d’abord : La CSP (Content Security Policy) est un en-tête de réponse qui indique au navigateur quels scripts peuvent s’exécuter et quels domaines peuvent charger des ressources. Le déploiement se fait en trois étapes : d’abord Report-Only pendant 14 jours pour collecter les sources de violation, puis affiner la liste blanche jusqu’à ce que les journaux de violation tombent à quelques cas par jour, et seulement alors passer en Enforce. Un constat contre-intuitif : une CSP mal configurée est plus dangereuse que pas de CSP du tout — activer unsafe-inline revient à construire un mur pour rien.

1. Ce que la CSP bloque réellement

La CSP diffuse ses règles via un en-tête de réponse HTTP, et le navigateur décide en fonction quelles ressources peuvent se charger. Elle protège principalement contre deux problèmes : les scripts malveillants injectés par XSS et l’intégration de domaines tiers non autorisés dans la page.

Ce n’est pas un pare-feu. La CSP ne bloque ni les injections SQL ni la compromission du serveur ; elle gère le chargement des ressources côté navigateur. Elle fonctionne en complément de HTTPS et HSTS. Pour configurer HTTPS, voir Configurer HTTPS sur un site indépendant.

Le problème courant des sites indépendants, c’est le trop grand nombre de scripts tiers : GA4, GTM, Hotjar, chat en ligne, pixels publicitaires. Chaque script ajouté exige d’ajouter un domaine à la liste blanche CSP, sinon le navigateur le bloque. Pour gérer les scripts tiers, voir Gérer les scripts tiers sur un site indépendant.

Un fait souvent négligé : la CSP n’a quasiment aucun impact négatif sur le SEO. Googlebot n’applique pas de restriction sur les ressources autres que JS, et une CSP bien configurée n’affecte pas l’indexation. Craindre que la CSP nuise au crawl est inutile.

Directive Ce qu’elle gère Valeur conseillée
default-src Toutes les ressources par défaut ‘self’
script-src Sources des scripts JS ‘self’ + domaines de statistiques
style-src Sources CSS ‘self’ ‘unsafe-inline’
img-src Sources des images ‘self’ data: + CDN
object-src Extension ‘none’ (obligatoire)
frame-ancestors Qui peut intégrer le site ‘none’

2. Déploiement en trois étapes : rapport, affinage, application

L’erreur la plus fréquente est d’activer directement l’en-tête Content-Security-Policy. Cela bloque immédiatement tous les scripts du site non inscrits sur la liste blanche : GA4, chat en ligne, pixels tombent tous en panne, et les équipes métier se plaignent aussitôt.

La bonne méthode consiste à commencer par l’en-tête Content-Security-Policy-Report-Only. Le navigateur signale les violations sans les bloquer ; vous collectez les journaux pendant deux semaines et ajoutez à la liste blanche tous les domaines réellement utilisés.

Exemple de scénario 1 : ajouter une CSP à un site WordPress, en commençant par Report-Only.

Deux jours plus tard, le rapport fait apparaître trois domaines : googletagmanager.com, hotjar.com et youtube.com.

Ajoutez-les un par un dans script-src et frame-src. Au bout de deux semaines, le rapport ne signale plus que quelques cas par jour ; passez alors en mode application.

Phase En-tête de réponse Action Durée
Première étape Content-Security-Policy-Report-Only Signaler sans bloquer 14 jours
Deuxième étape Idem, ajouter progressivement la liste blanche Les violations diminuent chaque jour Jusqu’à un chiffre
Troisième étape Content-Security-Policy Blocage réel Long terme
En permanence Ajouter report-to ou report-uri Collecter les signalements de violation Toujours actif

Les scripts inline sont le plus gros piège. Les thèmes WordPress et beaucoup d’extensions écrivent directement des <script> dans la page, et CSP bloque les inline par défaut. Deux solutions : soit extraire les scripts inline dans un fichier js externe, soit autoriser ce passage précis avec un hash sha256, plutôt que d’activer unsafe-inline par facilité.

style-src est plus permissif que script-src. L’éditeur Gutenberg et beaucoup de thèmes génèrent des styles inline, garder temporairement unsafe-inline sur style-src ne pose pas de gros problème.

Mais script-src ne doit jamais activer unsafe-inline, c’est la ligne de défense centrale de CSP contre le XSS. Il faut traiter différemment la tolérance de ces deux directives.

3. Risques de contournement : ne laissez pas CSP être une coquille vide

Un CSP mal configuré revient à ne pas en avoir. Les trois écritures suivantes rendent ce mur totalement inopérant.

La première consiste à activer unsafe-inline. Elle autorise l’exécution de n’importe quel script inline, y compris le script malveillant injecté par XSS, et la ligne de défense centrale de CSP tombe. La deuxième consiste à activer le joker *, ce qui revient à ne limiter aucune source. La troisième oublie object-src, et les anciens navigateurs peuvent encore contourner via Flash ou des extensions.

Exemple de scénario 2 : par facilité, on écrit ‘unsafe-inline’ dans script-src.

Résultat : deux mois plus tard, le site se fait injecter un script de phishing inline, et CSP ne bloque rien du tout.

La bonne méthode est d’utiliser un nonce, un nombre aléatoire à usage unique généré à chaque requête, pour n’autoriser que les scripts inline portant ce nombre.

Écriture erronée Risque Alternative
script-src * N’importe quel script tiers peut se charger Lister les domaines un par un en liste blanche
script-src ‘unsafe-inline’ Le script injecté par XSS s’exécute normalement Extraire dans un fichier externe ou utiliser nonce/hash
Ne pas écrire object-src Les vieilles extensions peuvent être détournées object-src ‘none’
Ne pas configurer frame-ancestors La page est imbriquée dans une iframe malveillante frame-ancestors ‘none’

CSP et conformité sont deux choses distinctes. Le consentement aux cookies du RGPD est un autre mécanisme, voir Conformité RGPD pour un site indépendant. CSP protège contre l’injection de scripts, il ne règle pas la question du consentement aux cookies. Pour la connexion et les permissions de fichiers au niveau serveur, voir Renforcement de la sécurité d’un site indépendant.

Comment choisir entre nonce et hash ? Pour un script inline fixe, utilisez un hash ; pour un script inline généré dynamiquement, utilisez un nonce. Dans un thème WordPress, le bout de code de suivi fixe se valide par hash ; les blocs de script dont le contenu change à chaque requête utilisent un nonce.

L’emplacement de déploiement compte aussi. Il vaut mieux envoyer l’en-tête de réponse CSP au niveau Nginx ou CDN, plutôt que de le faire produire par l’application PHP. Une sortie au niveau applicatif disparaît en cas de panne PHP, alors qu’un envoi au niveau CDN reste stable.

Emplacement de déploiement Stabilité Cas d’usage
Configuration Nginx Élevée, reste en place même si l’application tombe Serveur auto-hébergé
Règles CDN Élevée, effective dans le monde entier Si vous utilisez Cloudflare, etc.
Sortie de l’application PHP Faible, perdue en cas de panne Test temporaire

Le point de réception des rapports doit aussi être créé spécifiquement. L’adresse vers laquelle pointe report-uri ne doit pas être bloquée par CSP lui-même, sinon les rapports ne partent pas.

Pour un site autonome, vous pouvez utiliser un service de collecte de rapports existant, ou configurer un point de terminaison de journal dédié dans Nginx pour recevoir les signalements, écrire dans un fichier de journal séparé, sans passer par le journal de trafic du site principal.

Une fois le volume de rapports important, il faut agréger. Vous pouvez recevoir plusieurs centaines de signalements par jour, impossible de tout examiner un par un. Regroupez les statistiques par directive violée et par domaine bloqué, en surveillant surtout les nouveaux domaines ajoutés chaque jour.

Une idée fausse courante : croire qu’une fois le CSP en place, tout est réglé. En réalité, chaque ajout d’un nouveau script tiers, chaque mise à jour du thème, peut introduire une nouvelle source de violation.

Donc après le passage en Enforce, report-uri ne doit pas être désactivé. C’est votre seule source de signalement pour détecter « un script ajouté qu’on a oublié de mettre en liste blanche ».

Un mot aussi sur la compatibilité des navigateurs. Les navigateurs modernes (Chrome, Edge, Firefox, Safari des deux dernières années) prennent tous en charge CSP 3 de manière complète. Les vieux IE peuvent être ignorés, les visiteurs d’un site autonome B2B n’utilisent pratiquement pas IE.

Autre détail de déploiement : l’en-tête CSP doit être envoyé à la fois en http et en https. Si vous ne l’envoyez qu’en https, les requêtes en phase de retour à l’origine en http ne sont pas protégées par le CSP.

Après le passage en Enforce, il est conseillé de conserver en parallèle un en-tête Report-Only pendant un certain temps : à la fois blocage et signalement, et si quelque chose a été oublié, vous pourrez le voir dans les rapports.

Le CSP n’est pas un projet ponctuel. À chaque ajout d’un nouveau script tiers (support client, chat, vidéo, publicité), il faut d’abord observer en mode rapport qu’il apparaît dans les violations, puis ajouter le domaine correspondant à la liste blanche, et seulement ensuite passer en production.

Ajoutez la vérification CSP à votre liste de contrôle avant la mise en ligne d’un nouveau script : ajoutez le script et la liste blanche en même temps, n’attendez pas qu’après la mise en ligne un utilisateur signale « le composant ne s’affiche pas » pour penser au CSP.

Un critère de décision : si un script tiers ne peut être transformé en fichier externe, ni faire l’objet d’un calcul de hachage, il faut réévaluer si ce tiers vaut la peine d’être utilisé. Un service tiers qui dépend de unsafe-inline est en soi une dette technique.

Une fois le déploiement terminé, vérifiez page par page avec le panneau Security de la console du navigateur. Passez en revue la page d’accueil, la page produit, la page blog et la page formulaire, pour confirmer qu’aucune alerte de violation rouge n’apparaît.

Pour les pages qui échouent à la vérification, retournez dans les rapports chercher le domaine correspondant, ajoutez-le à la liste blanche et observez encore un jour. Ce cycle répété deux ou trois fois suffit à stabiliser.

Le CSP n’est pas un élément de sécurité qui se termine après un déploiement : il évolue sur le long terme avec votre bibliothèque de scripts tiers. À chaque ajout d’un nouveau script, il faut mettre à jour la liste blanche en même temps, sans jamais oublier de configurer le domaine d’un nouveau script tiers qui apparaît.

Source du rapport Signification Traitement
Violation script-src Nouveau script sans liste blanche Ajouter le domaine ou extraire le fichier externe
Violation img-src Image liée depuis un nouveau domaine Ajouter le CDN ou passer en chemin relatif
Violation frame-src Nouvelle iframe intégrée Ajouter le domaine vidéo ou le retirer
Violation base-uri Balise base injectée dans la page Rechercher immédiatement un XSS

FAQ — Questions fréquentes

Faut-il activer le CSP en mode forcé dès la mise en ligne ?
Non. Commencez par le mode rapport Content-Security-Policy-Report-Only pendant 14 jours : le navigateur signale les violations sans les bloquer. Ajoutez une à une à la liste blanche les domaines réels qui apparaissent dans les rapports, et une fois les violations tombées à quelques unités, passez au mode forcé Content-Security-Policy. Forcer d’emblée ferait tomber GA4, le chat en ligne et les pixels publicitaires.
Que faire quand un script inline d’un thème WordPress est bloqué par la CSP ?
Ne cédez pas à la facilité en activant unsafe-inline. Deux bonnes méthodes : premièrement, sortir le script inline dans un fichier js séparé et l’appeler avec src ; deuxièmement, pour les scripts inline qu’on doit garder, calculer un hachage sha256 et autoriser ce hachage précis dans script-src. unsafe-inline laisse aussi s’exécuter les scripts malveillants injectés par XSS, ce qui revient à une CSP inutile.
Quel est le lien entre la CSP, HTTPS et HSTS ?
Les trois se complètent sans se recouvrir. HTTPS gère le chiffrement du transport, HSTS force le navigateur à n’utiliser que HTTPS, la CSP contrôle quels scripts et ressources le navigateur peut charger. HTTPS est un prérequis ; la CSP vient par-dessus HTTPS pour bloquer en plus les XSS et les scripts tiers non autorisés. Installer la CSP sans HTTPS n’a aucun sens.
Pourquoi mes rapports CSP ne contiennent-ils que des violations ?
Cela signifie que la liste blanche est incomplète. Chaque rapport de violation indique de quel domaine vient le script bloqué : ajoutez ce domaine à la directive correspondante (script-src, img-src, frame-src, etc.). Les statistiques tierces, le chat client et les intégrations vidéo sont les oublis les plus fréquents. C’est tout l’intérêt du mode rapport : collecter proprement avant de forcer.
La CSP peut-elle bloquer les injections SQL ?
Non. La CSP agit côté navigateur et ne contrôle que le chargement des ressources ; elle ne bloque pas les injections SQL côté serveur. Les injections SQL se règlent par des requêtes préparées et un filtrage des entrées. La CSP sert surtout à bloquer les XSS : le script malveillant injecté par l’attaquant est empêché de s’exécuter, mais l’injection elle-même a déjà eu lieu sur le serveur.
Faut-il encore garder report-uri ?
Oui. Même après le passage en mode forcé Enforce, conservez report-to ou report-uri pour continuer à collecter les nouvelles violations. Les scripts tiers ajoutés et le code inline introduit par les mises à jour de thème apparaissent d’abord dans les rapports. Je conseille de brancher les remontées de violations sur un service de logs et de jeter un œil chaque jour aux domaines inhabituels.

Pour conclure

La difficulté de la CSP n’est pas d’écrire les règles, mais d’avoir la patience de faire tourner le mode rapport. Deux semaines d’observation pour des années de scripts maîtrisés : le calcul est vite fait.

Trois étapes pour passer à l’action : d’abord lancer Report-Only pendant 14 jours ; ajouter une à une à la liste blanche les domaines réels d’après les rapports et remplacer unsafe-inline par des hachages ; une fois les violations tombées à quelques unités, passer en mode forcé tout en gardant le rapport pour surveiller en continu.

Une phrase à retenir : le niveau de sécurité d’une CSP dépend de la propreté de sa liste blanche. Garder unsafe-inline et des jokers, c’est un mur qui n’a jamais été monté.

Cratère
Cratère Expert Cratère

Officiel de l'organisme · Cratère Crater

Cratère (Crater) est une société de services d'expansion internationale spécialisée dans le développement de sites WordPress autonomes, le référencement Google et la croissance globale GEO, au service des secteurs du matériel intelligent, de l'équipement industriel, du SaaS et des énergies nouvelles.

Capacités produitLivre blanc méthodologiqueRapports sectoriels
965partages
78articles de base de connaissances