Générateur de Content Security Policy
Génère les en-têtes Content-Security-Policy.
Build a Content-Security-Policy. Common keywords: 'self' 'none' 'unsafe-inline' 'unsafe-eval' 'strict-dynamic' data: https: blob:
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
- 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. - Ajoutez les origines dont vous avez réellement besoin, une directive à la fois. Séparez plusieurs sources par des espaces.
- Laissez une directive vide pour l’omettre ; les directives vides retombent sur
default-src. - 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.