MDN wants to learn about developers like you: https://qsurvey.mozilla.com/s3/MDN-dev-survey

Une Content Security Policy (CSP) ou politique de sécurité du contenu permet d'améliorer la sécurité des sites web en permettant de détecter et mitiger certains types d'attaques, dont les Cross Site Scripting (XSS) et les injections de contenu. Ces attaques peuvent être utilisées dans divers buts, comme le vol de données, le défacement de site ou la diffusion de malware.

CSP a été conçu pour être parfaitement rétro-compatible (sauf pour la version 2 dans laquelle existent des incompatibilités décrites explicitement comme telles, pour plus d'informations, se référer à la documentation du w3c (en anglais)). Les navigateurs qui ne supportent pas le CSP fonctionnent parfaitement avec les serveurs qui l'implémentent et inversement. Les navigateurs qui ne supportent les directives CSP les ignorent, et fonctionnent comme à leur habitude, en utilisant le standard same-origin policy (politique de même origine) pour les contenus. Dans le cas où un navigateur qui prend en charge CSP visite une page web servie par un serveur qui ne fournit pas de CSP, il va probablement utiliser le standard same-origin policy.

Pour activer CSP, vous devez configurer vos serveurs web pour ajouter aux réponses un en-tête (header) HTTP Content-Security-Policy. Vous pouvez rencontrer des documents qui mentionnent X-Content-Security-Policy comme en-tête, il s'agit d'une version obsolète qu'il n'est plus utile de supporter.

Une autre possibilité consiste à utiliser une balise <meta> pour configurer la politique, par exemple : <meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">

Menaces

Mitigation des attaques cross site scripting (XSS)

CSP a pour but premier de bloquer et rapporter les attaques XSS (injections de contenu). Les attaques XSS exploitent la confiance que les navigateurs ont dans le contenu reçu des serveurs. Des scripts malveillants peuvent être exécutés par le navigateur d'une victime parce que le navigateur fait confiance au serveur qui lui envoie des données même quand le contenu ne vient pas de là où il semble venir.

CSP permet aux administrateurs système de réduire ou éliminer les moyens de réaliser des attaques XSS en permettant de spécifier les domaines autorisés à fournir des scripts pour la page visitée. Un navigateur compatible avec la CSP n'exécute que les scripts qui provient d'une origine autorisée par la CSP reçue, en ignorant ceux qui ne sont pas autorisés. On peut ainsi bloquer les domaines non autorisés, les scripts inline (inclus dans une page HTML) ou associés à des événements via les attributs HTML dédiés.

Pour un niveau de protection le plus élevé possible, un site qui voudrait qu'aucun script ne puisse être exécuté peut désactiver tout simplement l'exécution de tout script.

Empêcher les écoutes du trafic

En plus de restreindre les domaines d'où peuvent être chargés des contenus, le serveur peut spécifier quels protocoles peuvent être utilisés, par exemple en forçant l'utilisation de HTTPS pour améliorer la sécurité. Une politique de sécurité complète pour la transmission des données peut non seulement forcer l'utilisation de TLS via HTTPS mais aussi forcer l'utilisation de sécurisés (qui ne peuvent être envoyés qu'en HTTPS) et indiquer de convertir automatiquement toutes les requêtes qui auraient été faites en HTTP simple en requêtes HTTPS. L'utilisation de l'en-tête Strict-Transport-Security to s'assurer que les navigateurs utilisent obligatoirement des connexions chiffrée en TLS (HTTPS).

Utiliser CSP

Configurer une CSP nécessite d'utiliser un en-tête HTTP Content-Security-Policy pour une page web et de spécifier une valeur pour contrôler les ressources que le navigateur est autoriser à charger pour cette page. Ainsi, un page qui charge et affiche des images peut autoriser les images stockées n'importe où mais n'autoriser les envois de formulaires que vers certaines adresses.

Créer votre politique CSP

On peut utiliser l'en-tête HTTP Content-Security-Policy pour définir la politique ainsi :

Content-Security-Policy: politique

La politique est une chaîne de caractères contenant la liste des règles qui constituent la politique CSP.

Écrire une politique

Une politique est définie par une série de règles qui décrivent chacune le comportement attendu pour un certain type de contenu ou pour l'ensemble des requêtes. Un politique peut inclure une règle default-src pour la politique par défaut qui s'applique aux ressources pour lesquelles aucune politique n'est définie. Pour les autres types de politique, on pourra de référer à la page default-src. Pour bloquer les scripts intégrés au code HTML (Javascript inline) et l'utilisation de eval(), une politique doit au moins contenir une directive default-src ou script-src. Pour bloquer les modifications de style intégrés au code HTML (CSS inline avec les attributs HTML <style>) et l'utilisation des balises style, une politique doit au moins contenir une directive default-src ou style-src.

Exemples pour les cas courants

Cette section propose des politiques CSP pour les scenarii les plus classiques.

Exemple 1

Pour un site dont tout le contenu est fourni par le site lui-même (sans inclure les sous-domaines) en HTTPS et qui n'utilise pas le referer des navigateurs :

Content-Security-Policy: default-src 'self'; upgrade-insecure-requests; referrer no-referrer

Exemple 2

Pour un site dont tout le contenu est fourni par le site lui-même ou par les sous-domaines de source-sure.example.net (qui peut être un autre site) :

Content-Security-Policy: default-src 'self' *.source-sure.example.net

Exemple 3

Pour un site dont les images peuvent venir de n'importe où, les musiques et vidéos de toto.local ou tata.local, les scripts par scripts.local :

Content-Security-Policy: default-src 'self'; img-src *; media-src toto.local tata.local; script-src scripts.local

Ici, les contenus doivent par défaut venir de la même origine que la page avec les exceptions précédemment décrites. Cela peut permettre aux utilisateurs d'afficher des images quelconques, mais de ne faire confiance qu'à certains domaines pour les musiques, vidéos et scripts.

Exemple 4

Pour un site dont les données sont au moins privées et pour lequel toutes les données devraient être transmises en HTTPS depuis un domaine précis :

Content-Security-Policy: default-src https://confidentiel.example.net

Cette politique force l'utilisation de HTTPS et exclus tout usage de contenu ne venant pas de https://confidentiel.example.net.

Example 5

Pour un webmail qui permet d'afficher des mails incluant de l'HTML, des images provenant de n'importe où mais pas de Javascript ou autres :

Content-Security-Policy: default-src 'self'; img-src *; child-src: *

Tester une politique

Pour faciliter le déploiement de CSP, on peut le configurer pour seulement reporter les violations de politique sans appliquer réellement la politique. Ainsi, on peut s'assurer que la politique ne bloque pas les usages du site en récupérant les rapports de violation de la politique en test. On peut aussi tester des modifications d'une politique en place via ce même mécanisme.

Pour cela, il suffit d'utiliser l'en-tête Content-Security-Policy-Report-Only, comme cela :

Content-Security-Policy-Report-Only: politique 

Si les en-tête HTTP Content-Security-Policy-Report-Only et Content-Security-Policy sont tous deux présents dans la réponse du serveur, les deux politiques seront respectées, ce qui permet le test d'une nouvelle potique quand il y en a déjà une en place.

Si une politique contient une directive report-uri valide, les navigateurs qui supportent CSP doivent envoyer un rapport pour chaque violation de la politique qu'ils détectent.

Gérer les rapports

Par défaut, les violations de la politique de sécurité ne sont pas rapportés. Pour avoir des rapports de violation, il faut une directive report-uri avec au moins une URL valide à laquelle envoyer les rapports :

Content-Security-Policy: default-src 'self'; report-uri http://reportcollector.example.com/collector.cgi

Il faut également configurer le serveur qui doit recevoir les rapports pour en faire quelque chose d'utile, par exemple les stocker si on veut juste pouvoir les examiner manuellement.

Syntaxe des rapports de violation de politique

Le report contient un objet JSON qui contient :

document-uri
L'URI du document qui pour lequel une violation de la politique est arrivée.
referrer
Le referer de ce document : l'URI du document qui a conduit au document où la violation a eu lieu.
blocked-uri
L'URI de la ressource qui a été bloquée par la politique CSP. Si la ressource vient d'une autre origine que le document principal, alors seuls le protocole, le nom de domaine et le port sont indiqués.
violated-directive
Le nom de la section de la politique qui a été violée.
original-policy
La politique CSP reçue par le client.

Exemple de rapport de violation de politique

Si l'on considère une page http://example.com/connexion.html, qui utilise la politique CSP suivante (qui interdit tout par défaut et autorise les feuilles de style CSS provenant de cdn.example.com) :

Content-Security-Policy: default-src 'none'; style-src cdn.example.com; report-uri /_/csp-reports

et qui contient le code HTML suivant :

<!DOCTYPE html>
<html>
  <head>
    <title>Connectez-vous</title>
    <link rel="stylesheet" href="css/style.css">
  </head>
  <body>
    ... Contenu ...
  </body>
</html>

Dans cette situation, les clients qui visiteraient cette page la verrait avec les styles de base de leur navigateur car les feuilles de style autorisées ne peuvent venir que de cdn.example.com et non du site lui-même (l'origine même de la page) comme <link rel="stylesheet" href="css/style.css"> l'indique au navigateur. En outre, un navigateur (qui supporte CSP) enverrait le rapport de violation de politique CSP suivant à l'adresse http://example.com/_/csp-reports à chaque visite de la page dont il est question :

{
  "csp-report": {
    "document-uri": "http://example.com/connexion.html",
    "referrer": "",
    "blocked-uri": "http://example.com/css/style.css",
    "violated-directive": "style-src cdn.example.com",
    "original-policy": "default-src 'none'; style-src cdn.example.com; report-uri /_/csp-reports"
  }
}

Comme vous pouvez le constater, le rapport inclus l'URI complète de la ressource dans blocked-uri. C'est n'est le cas en général. Ainsi, si la page avait essayé de charger la feuille de style http://anothercdn.example.com/stylesheet.css, le navigateur aurait indiqué seulement "blocked-uri": "http://anothercdn.example.com/", c'est à dire l'origine et non l'URI complète car l'origine de la feuille bloquée est différente de l'origine du site lui-même. La spécification de la CSP, disponible en anglais sur le site du W3C, explique les raisons de ce comportement qui peut surprendre de prime abord. En résumé, ce comportement évite les risques de diffuser des informations confidentielles qui pourraient être incluses dans les URI des ressources provenant d'autres origines.

Compatibilité avec les navigateurs

Fonctionnalité Chrome Edge Firefox Internet Explorer Opera Safari Servo
Content-Security-Policy2511423.021031574?
Content-Security-Policy-Report-Only251423.010157?
Fonctionnalité Android Chrome for Android Edge Mobile Firefox for Android IE Mobile Opera Mobile Safari Mobile
Content-Security-Policy4.4(Oui)(Oui)23.0??7.15
Content-Security-Policy-Report-Only4.4(Oui)(Oui)23.0??7.1

1. Implemented as X-Webkit-CSP header in Chrome 14.

2. Implemented as X-Content-Security-Policy header in Firefox 4.

3. Implemented as X-Content-Security-Policy header, only supporting 'sandbox' directive.

4. Implemented as X-Webkit-CSP header in Safari 6.

5. Implemented as X-Webkit-CSP header in iOS 5.1.

Références

Étiquettes et contributeurs liés au document

 Contributeurs à cette page : David-5-1
 Dernière mise à jour par : David-5-1,