Content Security Policy et votre CMP : faire fonctionner ensemble CSP et consentement
Deux couches de sécurité qui doivent s’accorder
Une Content Security Policy (CSP) indique au navigateur depuis quelles sources une page peut charger des scripts, des styles, des images, des frames et des requêtes réseau. Une plateforme de gestion du consentement fait le travail inverse : elle décide lesquels de ces scripts peuvent s’exécuter selon le choix de l’utilisateur. Quand les deux sont configurées séparément, elles entrent en collision. Le CMP ne se charge pas parce que la CSP le bloque, ou bien la CSP est assouplie au point, pour accueillir le CMP et les balises publicitaires, de ne plus rien protéger.
Ce guide explique de quelles directives CSP un CMP a généralement besoin, comment les nonces interagissent avec l’injection de scripts et comment déployer les changements sans casser votre bannière.
Ce dont un CMP a habituellement besoin côté CSP
Les exigences exactes dépendent du fournisseur ; partez donc toujours de la documentation de votre CMP. En général, vérifiez ces directives :
script-src— le domaine depuis lequel le script du CMP se charge, plus tout fichier de script supplémentaire qu’il charge.connect-src— les points de terminaison que le CMP appelle avecfetchou XHR, comme la configuration, la liste des fournisseurs, la géolocalisation et l’enregistrement du consentement.style-src— le domaine des feuilles de style, et éventuellement les styles en ligne si le CMP injecte un élément<style>ou définit des attributs de style.img-src— logos, icônes et tout pixel sans suivi utilisé par le CMP.font-src— si la bannière charge ses propres polices.frame-src— si le CMP utilise des iframes, par exemple pour partager le consentement entre domaines.
Sur les sites TCF, rappelez-vous que le CMP crée aussi sur la page une frame de localisation nommée __tcfapiLocator. Cette frame est créée sans source distante ; elle n’a donc normalement pas besoin d’une entrée frame-src, mais mieux vaut le confirmer pendant les tests.
Le problème du stub en ligne
La plupart des CMP vous demandent de placer un petit script en ligne — le stub — dans le head de la page, afin que d’autres scripts puissent mettre des appels en file d’attente avant le chargement du CMP principal. Une CSP stricte bloque les scripts en ligne sauf autorisation explicite. Vous avez trois options :
- Un nonce. Générez une valeur aléatoire par réponse, ajoutez-la à l’en-tête CSP sous la forme
'nonce-...'et à la balise<script>du stub. C’est l’option la plus souple pour les pages dynamiques. - Un hash. Ajoutez à
script-srcle hash SHA-256 du contenu exact du stub. Cela convient bien aux sites statiques, mais toute modification du stub, même un espace, le casse. - Auto-héberger le stub sous forme de fichier externe sur votre propre domaine, couvert par
'self'. Cela demande de veiller à ce qu’il se charge assez tôt.
Évitez 'unsafe-inline' comme raccourci. Il autorise tous les scripts en ligne, ce qui supprime une grande partie de la protection qu’offre la CSP.
Nonces et scripts injectés par le CMP
Un CMP qui bloque les scripts jusqu’au consentement fonctionne souvent en les retenant puis en les injectant plus tard. Avec une CSP à base de nonces, ces scripts injectés doivent eux aussi être autorisés. Il existe deux approches courantes :
- Propagation du nonce. Le CMP lit le nonce depuis sa propre balise script et l’ajoute à chaque script qu’il injecte. Vérifiez si votre CMP le prend en charge.
'strict-dynamic'. Ce mot-clé indique aux navigateurs compatibles de faire confiance aux scripts chargés par un script déjà approuvé. Cela simplifie la vie avec les gestionnaires de balises et les CMP qui injectent des scripts, mais cela signifie aussi que tout script auquel vous faites confiance peut en charger d’autres ; accordez donc votre confiance avec prudence.
Les gestionnaires de balises soulèvent la même question. Si vous chargez les balises publicitaires et analytiques via un gestionnaire de balises, suivez sa documentation sur les nonces et assurez-vous que le CMP et le gestionnaire de balises adoptent une approche cohérente.
Les balises publicitaires compliquent la CSP
La publicité programmatique charge des scripts et des frames depuis de nombreux domaines, et la liste change au gré des partenaires de demande. Les éditeurs font généralement l’un de ces deux choix :
- Une CSP stricte sur les pages sans publicité programmatique, et une politique plus large là où les publicités s’exécutent.
- Une politique centrée sur les directives qui restent gérables, comme
frame-ancestors,object-src 'none'etbase-uri, tandis que les sources de scripts restent plus larges.
Dans les deux cas, le CMP doit figurer explicitement dans la liste d’autorisation, et non être couvert seulement par un joker, afin qu’un changement de CSP ne désactive jamais silencieusement la bannière.
Déployer en mode report-only
Utilisez d’abord l’en-tête Content-Security-Policy-Report-Only. Le navigateur signale les violations sans rien bloquer, ce qui vous permet de voir ce qu’une nouvelle politique casserait.
- Déployez la politique en mode report-only avec un point de terminaison de rapport.
- Chargez les pages dans des profils de navigateur vierges et parcourez le parcours de consentement complet : première visite, tout accepter, tout refuser, choix personnalisé, retrait.
- Examinez les rapports de violation et la console du navigateur à la recherche de ressources du CMP bloquées.
- Ajustez la politique, puis passez en mode application.
- Laissez le reporting activé après l’application pour détecter les régressions.
Symptômes d’un conflit avec la CSP
- La bannière n’apparaît jamais, et la console affiche une violation de CSP pour le script du CMP.
- La bannière apparaît mais sans mise en forme, car
style-srcbloque son CSS. - Les choix ne sont pas enregistrés, car
connect-srcbloque l’appel d’enregistrement du consentement. - Les publicités ou l’analytique ne se chargent jamais après le consentement, car les scripts injectés n’ont pas de nonce.
__tcfapiest indéfini, car le stub en ligne a été bloqué.
Points clés à retenir
- Vérifiez
script-src,connect-src,style-src,img-srcetframe-srcpour votre CMP. - Autorisez le stub en ligne avec un nonce ou un hash, pas avec
'unsafe-inline'. - Assurez-vous que les scripts injectés après le consentement reçoivent un nonce ou sont couverts par
'strict-dynamic'. - Testez chaque parcours de consentement en mode report-only avant d’appliquer la politique.
- Gardez le CMP explicitement dans la liste d’autorisation pour que les changements de CSP ne puissent pas le désactiver.