Générateur de CSP

Donnez-nous l’adresse d’une vraie page. Nous lisons son HTML, listons tous les endroits d’où elle charge scripts, styles, images, polices et cadres, puis écrivons une politique que vous pouvez essayer en mode report-only, où elle ne peut rien casser.

Choisissez une page typique, pas seulement la page d’accueil : une fiche produit, un article, le formulaire de contact. Chacune peut charger depuis des endroits différents.

Ou essayez github.com, wordpress.org, www.bbc.com

Une liste d’invités pour vos propres pages

Un navigateur fait tout ce qu’une page lui dit de faire. Si le HTML dit « exécute ce script depuis ce serveur », il l’exécute. Cela devient dangereux le jour où quelqu’un d’autre réussit à ajouter une ligne à votre page, par un champ de commentaire que personne n’a nettoyé, une extension compromise ou une publicité. Le navigateur ne peut pas distinguer sa ligne de la vôtre.

Une Content-Security-Policy (CSP) est un en-tête de réponse où vous dites au navigateur, d’avance, d’où cette page a le droit de charger des choses. Elle se lit comme une liste d’invités, avec une ligne par sorte de ressource :

default-src 'self';
script-src 'self' https://cdn.example.com;
img-src 'self' data: https://images.example.net;
object-src 'none'

Chaque ligne est une directive. 'self' désigne l’origine de la page elle-même. Tout ce qui n’est pas sur la liste est refusé et le refus est consigné dans la console du navigateur.

Comment cette page construit le brouillon

Notre serveur récupère l’adresse une fois et analyse le HTML comme le ferait un navigateur, sans rien exécuter. Chaque adresse trouvée est réduite à son origine (schéma et hôte, sans chemin) puis classée :

DirectiveLue dans
script-src<script src>, les préchargements de modules et les adresses de scripts nommées dans des extraits de chargement en ligne
style-srcles liens de feuilles de style et les règles @import
img-src, font-srcles balises d’image, srcset, les icônes, les affiches, les préchargements et url() dans le CSS en ligne et dans les quatre premières feuilles de style de l’origine du site
frame-src, media-src, object-src, manifest-srcles cadres, l’audio et la vidéo, les plugins, le lien du manifeste
form-action, base-uriles cibles de formulaire et la balise <base>
connect-srcseulement les indications de préconnexion et les points d’accès documentés de quelques services trouvés dans la page (Google Analytics, Google Fonts, Cloudflare Web Analytics)

Le brouillon part de default-src 'self', ajoute une ligne par directive et ferme les portes qui n’ont pas de repli : object-src 'none', base-uri 'self', frame-ancestors 'self', plus upgrade-insecure-requests sur les pages HTTPS. Si la page envoie déjà une politique, dans un en-tête ou une balise meta, nous l’affichons et la comparons avec ce que la page charge.

La partie difficile : le code en ligne

Le code injecté est presque toujours en ligne, sous forme de bloc <script> ou d’attribut onclick écrit dans la page. Une politique qui vaut la peine interdit donc le code en ligne. Le piège, c’est que la plupart des sites en ont beaucoup de leur cru. L’outil compte les blocs de script, les attributs de gestionnaires d’événements, les liens javascript:, les blocs de style et les attributs style=, puis vous donne deux brouillons.

  • Le brouillon strict n’a pas de 'unsafe-inline'. C’est là que vous voulez arriver et il casserait le code en ligne compté plus haut.
  • Le brouillon de transition ajoute 'unsafe-inline' là où la page en a besoin. Il limite encore les sites d’où l’on peut charger des choses, mais il n’arrête plus les scripts en ligne injectés, ce qui explique pourquoi il est marqué comme faible.

Pour passer de l’un à l’autre, il y a trois voies. Déplacer le code dans des fichiers, faire poser par le serveur un nonce propre à chaque réponse sur chaque balise, ou lister dans la politique l’empreinte SHA-256 de chaque bloc. L’outil calcule ces empreintes pour les blocs de script trouvés. Elles ne servent que pour les blocs dont le texte ne change jamais.

Report-only d’abord, toujours

Envoyez le brouillon sous le nom Content-Security-Policy-Report-Only. Le navigateur n’impose rien et consigne ce qu’il aurait bloqué. Parcourez le site avec la console ouverte, ajoutez ce qui manque légitimement, puis recommencez jusqu’à ce que le journal se taise. Renommez alors l’en-tête en Content-Security-Policy. Vous obtenez des extraits pour Apache, nginx et une balise meta. La forme meta ne peut pas faire de report-only ni de frame-ancestors.

Le brouillon vient d’une seule page, lue une fois, sans rien exécuter. Il ne voit pas les requêtes que les scripts font après le chargement (balises d’analyse, widgets de clavardage, cadres de paiement, images chargées paresseusement), ce que reçoivent les visiteurs connectés, ni aucune autre page du site. Attendez-vous à ajouter des sources. Pour une note sur les en-têtes qu’une page envoie aujourd’hui, utilisez la note des en-têtes de sécurité.

Questions fréquentes

Une Content-Security-Policy va-t-elle casser mon site ?

Une politique appliquée bloque tout ce qu’elle ne liste pas : une politique erronée le fera donc. Une politique report-only ne peut rien casser, puisqu’elle se contente de consigner. Commencez par là, puis passez à l’application une fois que la console n’affiche plus aucune violation sur vos pages principales.

Une politique avec unsafe-inline vaut-elle la peine ?

En partie. Elle restreint encore les destinations des scripts, des cadres et des envois de formulaire, bloque les plugins et empêche le détournement de la balise <base>. Elle n’arrête pas un attaquant capable d’écrire un bloc de script dans la page et c’est la principale raison d’avoir une politique. Servez-vous-en comme d’une étape.

Quelle différence entre un nonce et une empreinte ?

Un nonce est une valeur aléatoire que le serveur génère pour chaque réponse et répète sur chaque balise de script qu’il approuve. Une empreinte est la signature d’un bloc de code précis, listée dans la politique. Les nonces conviennent aux pages construites à chaque requête. Les empreintes conviennent à quelques extraits statiques sur des pages qui peuvent être mises en cache.

Pourquoi les chemins sont-ils omis de la politique générée ?

La CSP accepte des chemins comme https://cdn.example.com/lib/, mais ils sont ignorés après une redirection et se brisent dès qu’un fichier bouge. La plupart des politiques déployées listent des origines. Si une origine héberge des fichiers de nombreuses parties, comme un CDN public, fixez aussi les fichiers exacts avec des empreintes d’intégrité.

Puis-je définir une CSP sur WordPress ou un autre CMS ?

Oui, par la configuration du serveur web ou une extension de sécurité qui envoie des en-têtes. Le thème et les extensions apportent une longue liste de scripts et de styles en ligne : commencez donc avec l’en-tête report-only et le brouillon de transition, puis réduisez le code en ligne une extension à la fois.

Où voir ce que la politique bloque ?

Dans l’onglet Console des outils de développement du navigateur. Chaque violation nomme la directive et l’adresse bloquée. Pour les recueillir auprès des visiteurs, ajoutez une directive report-uri ou report-to qui pointe vers un collecteur.