La Content-Security-Policy
méta-balise vous permet de réduire le risque d' attaques XSS en vous permettant de définir d'où les ressources peuvent être chargées, empêchant les navigateurs de charger des données à partir d'autres emplacements. Cela rend plus difficile pour un attaquant d'injecter du code malveillant dans votre site.
Je me suis cogné la tête contre un mur de briques en essayant de comprendre pourquoi j'obtenais des erreurs CSP les unes après les autres, et il ne semblait pas y avoir d'instructions concises et claires sur la façon dont cela fonctionne. Voici donc ma tentative d'expliquer brièvement certains points du CSP, en me concentrant principalement sur les choses que j'ai trouvé difficile à résoudre.
Par souci de concision, je n'écrirai pas la balise complète dans chaque échantillon. Au lieu de cela, je ne montrerai que la content
propriété, donc un exemple qui dit content="default-src 'self'"
signifie ceci:
<meta http-equiv="Content-Security-Policy" content="default-src 'self'">
1. Comment autoriser plusieurs sources?
Vous pouvez simplement lister vos sources après une directive en tant que liste séparée par des espaces:
content="default-src 'self' https://example.com/js/"
Notez qu'il n'y a pas de guillemets autour des paramètres autres que les paramètres spéciaux , comme 'self'
. De plus, il n'y a pas de deux-points ( :
) après la directive. Juste la directive, puis une liste de paramètres séparés par des espaces.
Tout ce qui est en dessous des paramètres spécifiés est implicitement autorisé. Cela signifie que dans l'exemple ci-dessus, ces sources seraient valides:
https://example.com/js/file.js
https://example.com/js/subdir/anotherfile.js
Cependant, ceux-ci ne seraient pas valables:
http://example.com/js/file.js
^^^^ wrong protocol
https://example.com/file.js
^^ above the specified path
2. Comment utiliser différentes directives, que font-elles chacune?
Les directives les plus courantes sont:
default-src
la politique par défaut pour le chargement de javascript, images, CSS, polices, requêtes AJAX, etc.
script-src
définit des sources valides pour les fichiers javascript
style-src
définit des sources valides pour les fichiers css
img-src
définit des sources valides pour les images
connect-src
définit des cibles valides pour XMLHttpRequest (AJAX), WebSockets ou EventSource. Si une tentative de connexion est effectuée avec un hôte non autorisé ici, le navigateur émulera une 400
erreur
Il y en a d'autres, mais ce sont ceux dont vous avez le plus besoin.
3. Comment utiliser plusieurs directives?
Vous définissez toutes vos directives à l'intérieur d'une méta-balise en les terminant par un point-virgule ( ;
):
content="default-src 'self' https://example.com/js/; style-src 'self'"
4. Comment gérer les ports?
Tout sauf les ports par défaut doit être autorisé explicitement en ajoutant le numéro de port ou un astérisque après le domaine autorisé:
content="default-src 'self' https://ajax.googleapis.com http://example.com:123/free/stuff/"
Ce qui précède entraînerait:
https://ajax.googleapis.com:123
^^^^ Not ok, wrong port
https://ajax.googleapis.com - OK
http://example.com/free/stuff/file.js
^^ Not ok, only the port 123 is allowed
http://example.com:123/free/stuff/file.js - OK
Comme je l'ai mentionné, vous pouvez également utiliser un astérisque pour autoriser explicitement tous les ports:
content="default-src example.com:*"
5. Comment gérer différents protocoles?
Par défaut, seuls les protocoles standard sont autorisés. Par exemple, pour autoriser WebSockets, ws://
vous devrez l'autoriser explicitement:
content="default-src 'self'; connect-src ws:; style-src 'self'"
^^^ web sockets are now allowed on all domains and ports
6. Comment autoriser le protocole de fichier file://
?
Si vous essayez de le définir comme tel, cela ne fonctionnera pas. Au lieu de cela, vous l'autoriserez avec le filesystem
paramètre:
content="default-src filesystem"
7. Comment utiliser les scripts en ligne et les définitions de style?
Sauf autorisation explicite, vous ne pouvez pas utiliser de définitions de style en ligne, de code à l'intérieur de <script>
balises ou dans des propriétés de balise comme onclick
. Vous les autorisez ainsi:
content="script-src 'unsafe-inline'; style-src 'unsafe-inline'"
Vous devrez également autoriser explicitement les images encodées en base64:
content="img-src data:"
8. Comment autoriser eval()
?
Je suis sûr que beaucoup de gens diraient que vous ne le faites pas, car «l'évaluation est mauvaise» et la cause la plus probable de la fin imminente du monde. Ces gens auraient tort. Bien sûr, vous pouvez définitivement percer des trous majeurs dans la sécurité de votre site avec eval, mais il a des cas d'utilisation parfaitement valides. Il suffit d'être intelligent pour l'utiliser. Vous le permettez ainsi:
content="script-src 'unsafe-eval'"
9. Que 'self'
signifie exactement ?
Vous pourriez 'self'
vouloir dire localhost, système de fichiers local ou quoi que ce soit sur le même hôte. Cela ne signifie rien de tout cela. Cela signifie des sources qui ont le même schéma (protocole), le même hôte et le même port que le fichier dans lequel la politique de contenu est définie. Servir votre site via HTTP? Pas de https pour vous alors, sauf si vous le définissez explicitement.
J'ai utilisé 'self'
dans la plupart des exemples car il est généralement logique de l'inclure, mais ce n'est en aucun cas obligatoire. Laissez-le de côté si vous n'en avez pas besoin.
Mais attendez une minute! Je ne peux pas simplement l'utiliser content="default-src *"
et en finir avec ça?
Non. Outre les failles de sécurité évidentes, cela ne fonctionnera pas non plus comme prévu. Même si certains documents affirment qu'il autorise tout, ce n'est pas vrai. Cela n'autorise pas l'inline ou les évales, donc pour vraiment, vraiment rendre votre site très vulnérable, vous utiliseriez ceci:
content="default-src * 'unsafe-inline' 'unsafe-eval'"
... mais j'espère que non.
Lectures complémentaires:
http://content-security-policy.com
http://en.wikipedia.org/wiki/Content_Security_Policy