appuyez sur ⌘K pour changer d’outil
CSP

Générateur de Content Security Policy

Génère les en-têtes Content-Security-Policy.

local
csp-generator

Build a Content-Security-Policy. Common keywords: 'self' 'none' 'unsafe-inline' 'unsafe-eval' 'strict-dynamic' data: https: blob:

§01 À PROPOS DE CET OUTIL

Vue d’ensemble

Une Content-Security-Policy indique au navigateur depuis quelles sources il a le droit de charger des ressources. Sa valeur pratique est plus étroite que son nom ne le suggère : la CSP ne corrige pas le cross-site scripting, elle le confine. Si une injection passe à travers votre encodage de sortie, c’est une politique stricte qui empêche le script injecté de s’exécuter, ou d’envoyer ce qu’il a volé vers le serveur d’un attaquant.

L’en-tête est une liste de directives séparées par des points-virgules, chacune nommant un type de ressource et les sources autorisées pour lui. Cet outil vous donne un champ par directive, pré-remplit une politique de départ raisonnable, et affiche l’en-tête assemblé au fil de votre saisie.

Utilisation

  1. Partez de la politique pré-remplie — default-src 'self', object-src 'none', base-uri 'self', frame-ancestors 'none'. C’est un plancher raisonnable pour un site qui sert ses propres ressources.
  2. Ajoutez les origines dont vous avez réellement besoin, une directive à la fois. Séparez plusieurs sources par des espaces.
  3. Laissez une directive vide pour l’omettre ; les directives vides retombent sur default-src.
  4. Copiez l’en-tête et déployez-le d’abord sous le nom Content-Security-Policy-Report-Only. Lisez les rapports de violation, corrigez la politique, puis basculez sur le nom d’en-tête qui applique.

Les mots-clés de source

Mot-cléSignification
'self'L’origine du document lui-même — mêmes schéma, hôte et port
'none'Rien du tout. N’a de sens que comme source unique
'unsafe-inline'Autorise les <script> / <style> en ligne et les gestionnaires d’événements en ligne
'unsafe-eval'Autorise eval, new Function, et les arguments de type chaîne passés à setTimeout
'strict-dynamic'Fait confiance aux scripts créés par un script déjà approuvé. Fait ignorer les listes d’hôtes autorisés de cette directive
data:Autorise les URI data:. Raisonnable pour img-src, dangereux pour script-src
https:N’importe quelle origine en HTTPS. Très large — signe habituel qu’il faut resserrer la politique
blob:Autorise les URL blob:, nécessaires aux Web Workers créés à partir de code généré

Les empreintes ('sha256-…') et les nonces ('nonce-…') sont les alternatives strictes à 'unsafe-inline'. Une empreinte couvre un script en ligne précis dont le contenu ne change jamais, ce qui convient aux sites générés statiquement. Un nonce est une valeur aléatoire fraîche à chaque réponse, ce qui convient aux pages rendues côté serveur. Vous ne pouvez pas utiliser de nonce sur un hébergement de fichiers statiques, faute d’étape par requête pour en générer un.

Les directives faciles à rater

base-uri n’est pas couverte par default-src. Sans elle, une balise <base href> injectée peut rediriger chaque URL relative de la page vers l’hôte d’un attaquant — y compris vos balises de script — sans jamais injecter le moindre script. Réglez-la sur 'self' ou 'none'.

form-action n’est pas non plus couverte par default-src. Sans elle, un formulaire injecté peut poster les saisies de vos utilisateurs vers une autre origine.

frame-ancestors remplace X-Frame-Options. Là où les deux se contredisent, les navigateurs modernes suivent la CSP : ne définir que l’ancien en-tête laisse donc les navigateurs récents libres de toute contrainte que vous pensiez avoir exprimée.

object-src 'none' vaut la peine d’être défini explicitement. Le contenu de greffon est une voie d’exécution héritée du passé, sans usage légitime sur un nouveau site.

connect-src est celle qu’on oublie. Elle régit fetch, XHR, les WebSockets et sendBeacon — c’est-à-dire exactement la manière dont un script injecté exfiltrerait des données. Un script-src serré accompagné d’un connect-src grand ouvert laisse ouverte la porte qu’il était censé fermer.

Exemples

Un site statique servant ses propres ressources, sans aucun script tiers :

default-src 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'none';
form-action 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:;
font-src 'self'; connect-src 'self'; upgrade-insecure-requests

Le même site avec une balise de mesure d’audience, en n’autorisant que les origines précises dont elle a besoin plutôt que https: :

script-src 'self' https://www.googletagmanager.com;
connect-src 'self' https://www.google-analytics.com

Collecter les rapports de violation

Le mode Report-Only n’a d’utilité que si vous lisez les rapports. Deux mécanismes existent, et la prise en charge par les navigateurs est partagée, si bien qu’un déploiement envoie généralement les deux.

report-uri /csp-report est la directive la plus ancienne. Elle est dépréciée mais reste celle dont la prise en charge est la plus large, et elle poste un corps JSON décrivant la ressource bloquée, la directive qui l’a bloquée et l’URL du document.

report-to est la remplaçante. Elle nomme un groupe de signalement configuré par un en-tête de réponse Reporting-Endpoints distinct, ce qui permet à un seul point d’entrée de recevoir ensemble les rapports de CSP, de dépréciation et d’intervention.

Quel que soit votre choix, attendez-vous au bruit. Les extensions de navigateur injectent scripts et styles dans les pages, et leurs violations sont indiscernables des vôtres dans le rapport. Le signal, c’est une violation qui apparaît chez de nombreux utilisateurs distincts pour la même URL de document et la même directive ; un blocked-uri isolé pointant vers un schéma chrome-extension: est le gestionnaire de mots de passe de quelqu’un.

Aucune des deux directives n’est disponible dans une balise <meta>. Le signalement exige le véritable en-tête HTTP.

Remarques

upgrade-insecure-requests réécrit les requêtes de sous-ressources en http:// vers https:// avant qu’elles ne soient émises. C’est une aide à la migration pour les pages à contenu mixte, pas un substitut à la correction des URL, et cela ne s’applique pas à la navigation vers d’autres sites.

style-src est généralement le dernier 'unsafe-inline' à disparaître, et souvent celui qui vaut la peine d’être gardé. Les attributs style en ligne ne peuvent pas être couverts par une empreinte — il faudrait 'unsafe-hashes' plus une empreinte pour chaque valeur d’attribut distincte — et l’injection CSS est un problème bien plus étroit que l’injection de script. Consacrer l’effort d’abord à script-src est le meilleur arbitrage.

Déployez avec Content-Security-Policy-Report-Only avant d’appliquer. Une politique trop stricte d’une seule directive ne se dégrade pas en douceur : elle casse la page silencieusement pour chaque visiteur dont le navigateur l’applique, et vous l’apprendrez de vos utilisateurs plutôt que de vos propres tests.

Si vous voulez vérifier ce qu’un site en production envoie actuellement, le vérificateur d’en-têtes HTTP affiche les en-têtes de réponse de n’importe quelle URL.

FAQ
Cet outil valide-t-il ma politique ?
Non. Il assemble le texte de l'en-tête à partir des champs que vous remplissez ; il ne vérifie pas que vos sources sont joignables ni que votre site fonctionne encore. La seule validation fiable est le mode Report-Only sur votre site réel, décrit plus bas.
Pourquoi 'unsafe-inline' est-il ignoré dès que j'ajoute une empreinte ?
C'est la spécification, pas un bug. Si un script-src contient la moindre source de type empreinte ou nonce, les navigateurs qui les comprennent ignorent entièrement 'unsafe-inline'. C'est une voie de mise à niveau délibérée : les anciens navigateurs reçoivent le mot-clé permissif, les récents reçoivent la liste stricte.
Quelle est la différence entre frame-src et frame-ancestors ?
frame-src contrôle ce que votre page a le droit d'intégrer. frame-ancestors contrôle qui a le droit d'intégrer votre page — c'est le remplaçant CSP de X-Frame-Options, et contrairement à la plupart des directives il n'est pas couvert par default-src.
Ai-je besoin de default-src si je liste toutes les autres directives ?
Cela vaut quand même la peine de le définir. default-src est le repli des directives de récupération que vous n'avez pas écrites, y compris celles ajoutées à la spécification après votre mise en production. Le régler sur 'self' fait qu'une future directive échoue en se fermant plutôt qu'en s'ouvrant.
Où placer l'en-tête terminé ?
Comme en-tête de réponse HTTP, idéalement au niveau du CDN ou du serveur web pour qu'il s'applique à chaque réponse. Une balise <meta http-equiv> fonctionne aussi mais ne peut pas exprimer frame-ancestors ni report-uri, et elle ne prend effet qu'au moment où l'analyseur l'atteint.