Content Security Policy (abrégé CSP) est un mécanisme de sécurité standardisé permettant de restreindre l'origine du contenu (tel qu'un script Javascript, une feuille de style etc.) dans une page web à certains sites autorisés. Il permet notamment de mieux se prémunir contre des attaques d'injection de code comme les attaques par cross-site scripting (abrégé XSS) ou par détournement de clic. Ces attaques se reposant essentiellement sur l'exécution de code malveillant sur un site où l'utilisateur se sent en confiance. Sa troisième version est actuellement un Candidat de Recommandation pour le groupe de travail W3C sur le Web Application Security[1].
CSP fournit une méthode standard pour que les propriétaires de sites web puissent déclarer les origines approuvées de contenu que les navigateurs devraient être autorisés à charger sur ce site. Les types couverts sont des scripts JavaScript, des feuilles de style CSS, des frames HTML (en), des Web Worker (en), des polices d'écriture, des images, des objets incorporables comme des Applets Java, ActiveX, des fichiers audio ou vidéo, et d'autres fonctionnalités d'HTML5.
La plupart des navigateurs modernes supportent ce mécanisme dans sa première version[2]. Ceux ne supportant pas cette spécification ignorent simplement l'en-tête, cela est donc transparent pour le visiteur.
Le standard, originellement appelé Content Restrictions, fut proposé par Robert Hansen en 2004[3], et fut implémenté en premier dans Firefox 4 qui fut vite suivi par d'autres navigateurs. La première version du standard fut publiée en 2012 en tant que recommandation W3C[4] qui engendra rapidement d'autres versions publiées en 2014. Un brouillon de la troisième version est toujours en cours d'élaboration avec de nouvelles fonctionnalités déjà adoptées par les navigateurs web[5].
Les noms d'en-tête suivant sont utilisés en tant qu'implémentations expérimentales de CSP :
Content-Security-Policy
: Nom d'en-tête standard proposé dans un document du W3C. Google Chrome le supporte depuis sa version 25[6]. Firefox le supporte depuis sa version 23[7], mise à jour du 6 août 2013[8]. WebKit le supporte depuis sa version 528 (nightly build)[9].X-WebKit-CSP
: En-tête expérimental et obsolète introduit dans Google Chrome et d'autres navigateurs basés sur WebKit (Safari) en 2011[10].X-Content-Security-Policy
: En-tête expérimental et obsolète introduit dans les navigateurs basés sur Gecko 2 (Firefox 4 à Firefox 22, Thunderbird 3.3, SeaMonkey 2.1)[11].Un site peut déclarer plusieurs en-têtes CSP différents. Chaque en-tête sera traité séparément par le navigateur.
Les attaques cross-site-scripting (XSS) exploitent la confiance que les navigateurs ont dans le contenu reçu des serveurs. Des scripts malveillants peuvent être exécutés sur des navigateurs de victimes car ceux-ci font aveuglément confiance au serveur qui leur envoie des données même quand celles-ci ne proviennent pas de là où elles semblent venir[12].
CSP permet aux administrateurs système de réduire ou éliminer les moyens de réaliser les attaques XSS en permettant de spécifier les domaines autorisés à fournir des scripts pour la page visitée. Les navigateurs compatibles avec CSP n'exécutent alors des scripts ne provenant que d'une origine autorisée par les règles CSP et ignorent ceux qui ne sont pas autorisés. On peut alors 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.
Le niveau de protection le plus élevé consisterait alors à n'autoriser l'exécution d'aucun script.
CSP permet également de forcer l'utilisation de HTTPS pour certains domaines, ainsi que l'utilisation de cookies sécurisés, ne pouvant être envoyés que via HTTPS, afin d'améliorer la sécurité. Outre l'utilisation détournée de CSP pour cette fonction, l'utilisation de l'en-tête Strict-Transport-Security
permet de s'assurer que les navigateurs utilisent obligatoirement des connexions chiffrées en TLS (HTTPS).
CSP peut être activé de deux manières différentes par un serveur web :
Content-Security-Policy
est ajouté dans les réponses du serveur.<meta>
est ajoutée dans le code HTML afin de définir la règle. Par exemple : <meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">
L'en-tête est alors suivie d'une chaîne de caractères contenant la liste des règles constituant la règle CSP : Content-Security-Policy: règle
. Une règle CSP permet de spécifier des valeurs afin de contrôler les ressources que le navigateur est autorisé à charger pour la page donnée.
Une règle est définie par une série de directives qui décrivent chacune un comportement attendu pour un certain type de contenu ou pour l'ensemble des requêtes.
Trois directives courantes sont :
default-src
: qui s'applique aux ressources pour lesquelles aucune règle n'est définie[13].script-src
: qui définit des sources valides pour des scripts JavaScript[14].style-src
: qui définit des sources valides pour des feuilles de style CSS.Content-Security-Policy: default-src 'self';
source-sure.example.net
: Content-Security-Policy: default-src 'self' *.source-sure.example.net;
Content-Security-Policy: default-src https://confidentiel.example.net
Cette règle force l'utilisation de HTTPS et exclut tout usage de contenu ne venant pas de https://confidentiel.example.net
.Afin de tester le déploiement de CSP sur un serveur, on peut le configurer pour rapporter les violations de règle sans pour autant appliquer réellement la règle. De telle façon, on ne bloque pas les usages du site en récupérant les rapports de violation de la règle en phase de test.
Pour cela, il suffit d'utiliser l'en-tête Content-Security-Policy-Report-Only
(CSPRO)[15] de la même façon que CSP :
Content-Security-Policy-Report-Only: règle
Si les en-têtes HTTP Content-Security-Policy-Report-Only
et Content-Security-Policy
sont tous deux présents dans une réponse du serveur, les deux règles seront respectées, ce qui permet de tester une nouvelle règle tout en gardant l'usage de règles préexistantes. Les règles de CSP sont appliquées tandis que celles de CSPRO génèrent des rapports mais ne sont pas appliquées.
Si jamais l'exécution d'un script ou une ressource demandée viole la Politique, le navigateur émettra une requête POST
aux URL spécifiées dans report-uri
, qui contiendra les détails de la violation. Il faut donc que la directive report-uri
soit spécifiée avec au moins une URL valide.
Par exemple :
Content-Security-Policy: default-src 'self'; report-uri http://reportcollector.example.com/collector.cgi
Les rapports d'erreur CSP sont des structures JSON standards qui peuvent être capturées tout aussi bien par l'API de l'application utilisée ou bien par des serveurs publiques de rapport d'erreur CSP.