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. Une 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 scenarios 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

Update compatibility data on GitHub
OrdinateurMobile
ChromeEdgeFirefoxInternet ExplorerOperaSafariWebview AndroidChrome pour AndroidEdge MobileFirefox pour AndroidOpera pour AndroidSafari pour iOSSamsung Internet
Content-Security-PolicyChrome Support complet 25
Notes
Support complet 25
Notes
Notes Implemented as X-Webkit-CSP header in Chrome 14.
Edge Support complet 14Firefox Support complet 23
Notes
Support complet 23
Notes
Notes Implemented as X-Content-Security-Policy header in Firefox 4.
IE Support complet 10
Notes
Support complet 10
Notes
Notes Implemented as X-Content-Security-Policy header, only supporting 'sandbox' directive.
Opera Support complet 15Safari Support complet 7
Notes
Support complet 7
Notes
Notes Implemented as X-Webkit-CSP header in Safari 6.
WebView Android Support complet OuiChrome Android Support complet OuiEdge Mobile Support complet OuiFirefox Android Support complet 23Opera Android ? Safari iOS Support complet 7.1
Notes
Support complet 7.1
Notes
Notes Implemented as X-Webkit-CSP header in iOS 5.1.
Samsung Internet Android Support complet Oui
base-uriChrome Support complet 40Edge Aucun support NonFirefox Support complet 35IE Aucun support NonOpera Support complet 27Safari Support complet 10WebView Android Support complet OuiChrome Android Support complet OuiEdge Mobile Aucun support NonFirefox Android Support complet 35Opera Android ? Safari iOS Support complet 9.3Samsung Internet Android Support complet Oui
block-all-mixed-contentChrome Support complet OuiEdge ? Firefox Support complet 48IE Aucun support NonOpera Support complet OuiSafari ? WebView Android Support complet OuiChrome Android Support complet OuiEdge Mobile ? Firefox Android Support complet 48Opera Android ? Safari iOS ? Samsung Internet Android Support complet Oui
child-src
Obsolète
Chrome Support complet 40Edge Support complet 15Firefox Support complet 45IE Aucun support NonOpera Support complet 27Safari Support complet 10WebView Android Support complet OuiChrome Android Support complet OuiEdge Mobile Aucun support NonFirefox Android Support complet 45Opera Android ? Safari iOS Support complet 9.3Samsung Internet Android Support complet Oui
connect-srcChrome Support complet 25Edge Support complet 14Firefox Support complet 23
Notes
Support complet 23
Notes
Notes Prior to Firefox 50, ping attributes of <a> elements weren't covered by connect-src.
IE Aucun support NonOpera Support complet 15Safari Support complet 7WebView Android Support complet OuiChrome Android Support complet OuiEdge Mobile ? Firefox Android Support complet 23Opera Android ? Safari iOS Support complet 7.1Samsung Internet Android Support complet Oui
default-srcChrome Support complet 25Edge Support complet 14Firefox Support complet 23IE Aucun support NonOpera Support complet 15Safari Support complet 7WebView Android Support complet OuiChrome Android Support complet OuiEdge Mobile ? Firefox Android Support complet 23Opera Android ? Safari iOS Support complet 7.1Samsung Internet Android Support complet Oui
disown-opener
Expérimentale
Chrome Aucun support NonEdge Aucun support NonFirefox Aucun support NonIE Aucun support NonOpera Aucun support NonSafari Aucun support NonWebView Android Aucun support NonChrome Android Aucun support NonEdge Mobile Aucun support NonFirefox Android Aucun support NonOpera Android Aucun support NonSafari iOS Aucun support NonSamsung Internet Android Aucun support Non
font-srcChrome Support complet 25Edge Support complet 14Firefox Support complet 23IE Aucun support NonOpera Support complet 15Safari Support complet 7WebView Android Support complet OuiChrome Android Support complet OuiEdge Mobile ? Firefox Android Support complet 23Opera Android ? Safari iOS Support complet 7.1Samsung Internet Android Support complet Oui
form-actionChrome Support complet 40Edge Support complet 15Firefox Support complet 36IE Aucun support NonOpera Support complet 27Safari Support complet 10WebView Android Support complet OuiChrome Android Support complet OuiEdge Mobile Aucun support NonFirefox Android Support complet 36Opera Android ? Safari iOS Support complet 9.3Samsung Internet Android Support complet Oui
frame-ancestorsChrome Support complet 40Edge Support complet 15Firefox Support complet 33
Notes
Support complet 33
Notes
Notes Before Firefox 58, frame-ancestors is ignored in Content-Security-Policy-Report-Only.
IE Aucun support NonOpera Support complet 26Safari Support complet 10WebView Android ? Chrome Android Support complet OuiEdge Mobile Aucun support NonFirefox Android Support complet 33
Notes
Support complet 33
Notes
Notes Before Firefox for Android 58, frame-ancestors is ignored in Content-Security-Policy-Report-Only.
Opera Android ? Safari iOS Support complet 9.3Samsung Internet Android Support complet Oui
frame-srcChrome Support complet 25Edge Support complet 14Firefox Support complet 23IE Aucun support NonOpera Support complet 15Safari Support complet 7WebView Android Support complet OuiChrome Android Support complet OuiEdge Mobile ? Firefox Android Support complet 23Opera Android ? Safari iOS Support complet 7.1Samsung Internet Android Support complet Oui
img-srcChrome Support complet 25Edge Support complet 14Firefox Support complet 23IE Aucun support NonOpera Support complet 15Safari Support complet 7WebView Android Support complet OuiChrome Android Support complet OuiEdge Mobile ? Firefox Android Support complet 23Opera Android ? Safari iOS Support complet 7.1Samsung Internet Android Support complet Oui
manifest-srcChrome Support complet OuiEdge Aucun support NonFirefox Support complet 41IE Aucun support NonOpera Support complet OuiSafari Aucun support NonWebView Android Support complet OuiChrome Android Support complet OuiEdge Mobile Aucun support NonFirefox Android Support complet 41Opera Android ? Safari iOS Aucun support NonSamsung Internet Android Support complet Oui
media-srcChrome Support complet 25Edge Support complet 14Firefox Support complet 23IE Aucun support NonOpera Support complet 15Safari Support complet 7WebView Android Support complet OuiChrome Android Support complet OuiEdge Mobile ? Firefox Android Support complet 23Opera Android ? Safari iOS Support complet 7.1Samsung Internet Android Support complet Oui
navigate-to
Expérimentale
Chrome Aucun support NonEdge Aucun support NonFirefox Aucun support NonIE Aucun support NonOpera Aucun support NonSafari Aucun support NonWebView Android Aucun support NonChrome Android Aucun support NonEdge Mobile Aucun support NonFirefox Android Aucun support NonOpera Android Aucun support NonSafari iOS Aucun support NonSamsung Internet Android Aucun support Non
object-srcChrome Support complet 25Edge Support complet 14Firefox Support complet 23IE Aucun support NonOpera Support complet 15Safari Support complet 7WebView Android Support complet OuiChrome Android Support complet OuiEdge Mobile ? Firefox Android Support complet 23Opera Android ? Safari iOS Support complet 7.1Samsung Internet Android Support complet Oui
plugin-typesChrome Support complet 40Edge Support complet 15Firefox Aucun support Non
Notes
Aucun support Non
Notes
Notes See bug 1045899.
IE Aucun support NonOpera Support complet 27Safari Support complet 10WebView Android Support complet OuiChrome Android Support complet OuiEdge Mobile Aucun support NonFirefox Android Aucun support NonOpera Android ? Safari iOS Support complet 9.3Samsung Internet Android Support complet Oui
referrer
ObsolèteNon-standard
Chrome Aucun support 33 — 56Edge Aucun support NonFirefox Aucun support 37 — 62IE Aucun support NonOpera Aucun support ? — 43Safari Aucun support NonWebView Android Aucun support 37 — 56Chrome Android Aucun support 33 — 56Edge Mobile Aucun support NonFirefox Android Aucun support 37 — 62Opera Android Aucun support ? — 43Safari iOS Aucun support NonSamsung Internet Android Support complet Oui
report-sample
Expérimentale
Chrome Support complet 59Edge ? Firefox ? IE ? Opera Support complet 46Safari ? WebView Android Support complet 59Chrome Android Support complet 59Edge Mobile ? Firefox Android ? Opera Android Support complet 46Safari iOS ? Samsung Internet Android Support complet 7.0
report-toChrome Aucun support NonEdge Aucun support NonFirefox Aucun support NonIE Aucun support NonOpera Aucun support NonSafari Aucun support NonWebView Android Aucun support NonChrome Android Aucun support NonEdge Mobile Aucun support NonFirefox Android Aucun support NonOpera Android Aucun support NonSafari iOS Aucun support NonSamsung Internet Android Aucun support Non
report-uri
Obsolète
Chrome Support complet 25Edge Support complet 14Firefox Support complet 23IE Aucun support NonOpera Support complet 15Safari Support complet 7WebView Android Support complet OuiChrome Android Support complet OuiEdge Mobile ? Firefox Android Support complet 23Opera Android ? Safari iOS Support complet 7.1Samsung Internet Android Support complet Oui
require-sri-for
Expérimentale
Chrome Support complet 54Edge Aucun support NonFirefox Support complet 49
Désactivée
Support complet 49
Désactivée
Désactivée From version 49: this feature is behind the security.csp.experimentalEnabled preference (needs to be set to true). To change preferences in Firefox, visit about:config.
IE Aucun support NonOpera Support complet 41Safari Aucun support NonWebView Android Support complet 54Chrome Android Support complet 54Edge Mobile Aucun support NonFirefox Android Support complet 49
Désactivée
Support complet 49
Désactivée
Désactivée From version 49: this feature is behind the security.csp.experimentalEnabled preference (needs to be set to true). To change preferences in Firefox, visit about:config.
Opera Android Support complet 41Safari iOS Aucun support NonSamsung Internet Android Support complet 6.0
sandboxChrome Support complet 25Edge Support complet 14Firefox Support complet 50IE Support complet 10Opera Support complet 15Safari Support complet 7WebView Android Support complet OuiChrome Android Support complet OuiEdge Mobile ? Firefox Android Support complet 50Opera Android ? Safari iOS Support complet 7.1Samsung Internet Android Support complet Oui
script-srcChrome Support complet 25Edge Support complet 14Firefox Support complet 23IE Aucun support NonOpera Support complet 15Safari Support complet 7WebView Android Support complet OuiChrome Android Support complet OuiEdge Mobile ? Firefox Android Support complet 23Opera Android ? Safari iOS Support complet 7.1Samsung Internet Android Support complet Oui
strict-dynamicChrome Support complet 52Edge Aucun support NonFirefox Support complet 52IE Aucun support NonOpera Support complet 39Safari Aucun support NonWebView Android Support complet 52Chrome Android Support complet 52Edge Mobile Aucun support NonFirefox Android Aucun support NonOpera Android Support complet 39Safari iOS Aucun support NonSamsung Internet Android Support complet 6.0
style-srcChrome Support complet 25Edge Support complet 14Firefox Support complet 23IE Aucun support NonOpera Support complet 15Safari Support complet 7WebView Android Support complet OuiChrome Android Support complet OuiEdge Mobile ? Firefox Android Support complet 23Opera Android ? Safari iOS Support complet 7.1Samsung Internet Android Support complet Oui
upgrade-insecure-requestsChrome Support complet 43Edge Aucun support Non
Notes
Aucun support Non
Notes
Notes Under consideration for future release.
Firefox Support complet 42IE Aucun support NonOpera Support complet 30Safari Support complet 10.1WebView Android Support complet 43Chrome Android Support complet 43Edge Mobile Aucun support NonFirefox Android Support complet 42Opera Android Support complet 30Safari iOS Support complet 10.3Samsung Internet Android Support complet 4.0
worker-srcChrome Support complet 59
Notes
Support complet 59
Notes
Notes Chrome 59 and higher skips the deprecated child-src directive.
Edge Aucun support NonFirefox Support complet 58IE Aucun support NonOpera Support complet 48Safari Aucun support NonWebView Android Support complet 59
Notes
Support complet 59
Notes
Notes Chrome 59 and higher skips the deprecated child-src directive.
Chrome Android Support complet 59
Notes
Support complet 59
Notes
Notes Chrome 59 and higher skips the deprecated child-src directive.
Edge Mobile Aucun support NonFirefox Android Support complet 58Opera Android Support complet 48Safari iOS Aucun support NonSamsung Internet Android Support complet 7.0

Légende

Support complet  
Support complet
Aucun support  
Aucun support
Compatibilité inconnue  
Compatibilité inconnue
Fonctionnalité expérimentale. Celle-ci peut être amenée à changer par la suite.
Fonctionnalité expérimentale. Celle-ci peut être amenée à changer par la suite.
Fonctionnalité non-standard. Celle-ci peut être incorrectement supportée par les autres navigateurs.
Fonctionnalité non-standard. Celle-ci peut être incorrectement supportée par les autres navigateurs.
Obsolète. Les nouveaux sites web ne doivent pas utiliser cette fonctionnalité.
Obsolète. Les nouveaux sites web ne doivent pas utiliser cette fonctionnalité.
Voir les notes d'implémentation.
Voir les notes d'implémentation.
Une action explicite de l'utilisateur est nécessaire pour activer cette fonctionnalité.
Une action explicite de l'utilisateur est nécessaire pour activer cette fonctionnalité.

A specific incompatibility exists in some versions of the Safari web browser, whereby if a Content Security Policy header is set, but not a Same Origin header, the browser will block self-hosted content and off-site content, and incorrectly report that this is due to a the Content Security Policy not allowing the content.

Références

Étiquettes et contributeurs liés au document

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