Le contenu actif sur les sites Web, par exemple Ja­vaS­cript, CSS et ActiveX, re­pré­sente un risque de sécurité pour les in­ter­nautes et les ex­ploi­tants de sites Web. En effet, ces contenus peuvent être touchés par le Cross-Site scripting. C’est pourquoi, la Content Security Policy (CSP) ou politique de sécurité du contenu, a été in­tro­duite afin de s’assurer que les pages Internet puissent être utilisées sans doute et hé­si­ta­tion. Le standard de sécurité est conçu pour se protéger contre les attaques mal­veil­lantes et est désormais pris en charge par la plupart des na­vi­ga­teurs Web. Le mécanisme de sécurité protège à la fois les sites Web et les in­ter­nautes. Mais qu’est-ce qui se cache derrière la CSP et comment fonc­tionne-il ?

Dé­ve­lop­pe­ment de la Content Security Policy

Content Security Policy remonte à 2004, à l’époque connu encore sous le nom de « Content-Res­tric­tion ». Sa création s’explique par les lacunes crois­santes en termes de sécurité des scripts Internet. Le Cross-Site scripting (XSS), une méthode cri­mi­nelle d’in­fil­tra­tion de code dans un site Web, re­pré­sente un risque par­ti­cu­lier pour les in­ter­nautes. Même si les uti­li­sa­teurs appellent un site Web qui est digne de confiance, un script s’y exécute et charge des données mal­veil­lantes à partir d’une source externe. Les cy­ber­cri­mi­nels utilisent les vul­né­ra­bi­li­tés pour commenter les fonctions du site Web par exemple. De cette façon, ils peuvent accéder à des or­di­na­teurs per­son­nels sans même que les in­ter­nautes en soient cons­cients. La plupart des Web­mas­ters ne re­mar­quent pas non plus qu’un code étranger a été inséré.

Pour résoudre ce problème, la Fondation Mozilla a été à l’ini­tia­tive du dé­ve­lop­pe­ment de CSP. L’avantage de ce mécanisme de sécurité est que des règles peuvent être définies dans le na­vi­ga­teur : les scripts que le logiciel est autorisé à modifier et ceux qui ne le sont pas. Pour cela, la Content Security Policy utilise des en-têtes HTTP.

Remarque

la fondation Mozilla est l’or­ga­ni­sa­tion derrière le dé­ve­lop­pe­ment du na­vi­ga­teur Firefox. L’organisme à but non lucratif est res­pon­sable de la direction des projets et des in­no­va­tions de Mozilla sur Internet. La fondation a été fondée par d’anciens employés de Netscape qui avaient développé alors l’un des premiers na­vi­ga­teurs Web.

Comment fonc­tionne la Content Security Policy ?

Lors de la com­mu­ni­ca­tion sur Internet, le client et le serveur échangent des données via le protocole HTTP (Hypertext Transfer Protocol). Les champs d’en-tête HTTP sont une partie im­por­tante des requêtes et des réponses : les pa­ra­mètres et arguments im­por­tants pour l’échange des deux in­ter­lo­cu­teurs (serveur et client) sont transmis dans ces derniers. Ils sont gé­né­ra­le­ment divisés en champs de requête et de réponse et peuvent contenir des in­for­ma­tions sur le jeu de ca­rac­tères, la langue et les cookies, par exemple. CSP est im­plé­menté comme un champ d’en-tête de réponse.

L’en-tête Content Security Policy est créé par le Webmaster et inséré sur chaque sous-page du site Web sur laquelle le mécanisme de sécurité doit s’appliquer. En tant qu’ex­ploi­tant du site Web, vous avez la pos­si­bi­lité de définir dif­fé­rentes pré­cau­tions de sécurité pour chaque page in­di­vi­duelle. Vous pouvez mettre en œuvre le concept de sécurité plus fa­ci­le­ment en créant des fichiers .htaccess dans les mêmes dossiers (ou hié­rar­chi­que­ment su­pé­rieurs) que les pages Web cor­res­pon­dantes, ou en ancrant CSP di­rec­te­ment dans la con­fi­gu­ra­tion du serveur.

Note

si, en tant qu’in­ter­naute, vous souhaitez vérifier que votre na­vi­ga­teur prend en charge Content Security Policy, vous pouvez exécuter le CSP Browser Test. Il essaie de charger des scripts et des images provenant de sources externes (inof­fen­sives) et vous indique si cela a réussi. Votre na­vi­ga­teur est sûr s’il ne charge pas les sources externes, c’est à dire qu’il comprend et utilise le CSP.

Dans le sens de la Content Security Policy et pour éviter le Cross-Site scripting, les res­pon­sables Web devraient stocker tous les scripts dans des fichiers séparés au lieu de les intégrer di­rec­te­ment dans le code source de la page d’accueil. Le CSP fonc­tionne alors selon le principe de la liste blanche (Whitelist) : l’en-tête énumère les sources à partir des­quelles les scripts et les données peuvent être chargés. Si un script externe a été inséré dans le code HTML de la page sans être reconnu et essaie main­te­nant de charger des données externes, le na­vi­ga­teur de l’uti­li­sa­teur doit alors l’interdire. Par défaut, un CSP bloque tous les scripts qui sont di­rec­te­ment dans le code (scripts en ligne). Cela protège à la fois le site Web et l’in­ter­naute et surtout leurs données sensibles.

Les ma­ni­pu­la­tions par le biais du Cross-Site scripting sont re­la­ti­ve­ment faciles pour les cy­ber­cri­mi­nels. Presque toutes les pages du Web ont un champ de saisie : par exemple la fonction de com­men­taire, la barre de recherche ou encore le champ de connexion. Au lieu d’un simple texte, des scripts peuvent aussi y être insérés. Si le serveur n’est pas cor­rec­te­ment sécurisé, les criminels mettent en places de cette façon des in­ter­faces d’ha­me­çon­nage et im­mo­bi­li­sent l’ensemble du site Web ou prennent le contrôle du na­vi­ga­teur Web de l’uti­li­sa­teur par le biais d’un logiciel mal­veil­lant. La CSP (ou plus exac­te­ment le champ d’en-tête cor­res­pon­dant) indique au na­vi­ga­teur Web à partir de quelles sources il peut charger des données. Si la « Politique » est im­plé­men­tée dans le code du site Web, la tentative de ré­cu­pé­ra­tion du code introduit via XSS est suivie d’un message d’erreur. En utilisant la Content Security Policy, les Web­mas­ters peuvent aussi effectuer de nombreux autres réglages, par exemple par le biais de ces di­rec­tives :

  • base-uri : limite les URL qui peuvent ap­pa­raître dans l’élément <base> de la page Web.
  • child-src : détermine à partir de quelles sources, les données peuvent ap­pa­raître dans les trames, par exemple pour les vidéos em­bar­quées de four­nis­seurs tiers.
  • connect-src : limite les sources avec les­quelles la page peut se connecter, par exemple via des liens.
  • font-src : détermine les sources à partir des­quelles les polices peuvent être chargées.
  • form-action : apporte une liste de critères d’éva­lua­tion valides dans les for­mu­laires.
  • frame-ancestors : détermine quels domaines peuvent inclure la page dans les Frames et iFrames.
  • img-src : limite les sources à partir des­quelles les images peuvent être chargées.
  • media-src : spécifie à partir de quelles sources les formats audio et vidéo peuvent être chargés.
  • object-src : définit le contrôle de Flash et d’autres plugins.
  • plugin-types : limite les types de plugins
  • report-uri : spécifie une URL à laquelle les rapports sont envoyés si les mesures de sécurité ont été violées.
  • script-src : détermine quelles sources sont au­to­ri­sées pour Ja­vaS­cript
  • style-src : fonc­tionne comme script-src, mais est utilisé pour les feuilles de style.
  • upgrade-insecure-requests : définit que les pages non sé­cu­ri­sées sont traitées comme des pages HTTPS avec HTTP.
  • Sandbox : déplace la page dans un Sandbox ou les for­mu­laires, pop-ups, scripts, etc. sont interdits.

Ces di­rec­tives ne sont valables que si elles sont ex­pli­ci­te­ment définies. Dans le cas contraire, elles sont ouvertes par défaut et re­pré­sen­tent donc une faille de sécurité. Cependant, ceci peut être ici changé avec default-src : vous pouvez définir l’état par défaut de toutes les di­rec­tives se terminant par –src. Par exemple, au lieu de la laisser ouverte, vous dé­fi­nis­sez que seules les données de votre propre site Web peuvent être chargées, à moins que vous n’ayez alors spécifié le contraire dans l’en-tête HTTP d’une page Web in­di­vi­duelle. Ajoutez ensuite d’autres sources dans les di­rec­tives séparées.

Vous pouvez saisir un nombre quel­conque de di­rec­tives dans la zone d’en-tête. Si vous voulez inclure plusieurs di­rec­tives, séparez-les par des points virgules. De plus, en tant que Webmaster, vous devez spécifier toutes les sources dans une directive. Les citations multiples des mêmes di­rec­tives avec des sources sup­plé­men­taires comme dans l’exemple suivant ne sont pas au­to­ri­sées :

script-src exemple1.local; script-src exemple2.local

Dans ce cas, seule la première source est per­ti­nente, la seconde serait ignorée par le client. Vous devez plutôt noter les deux sources dans une directive :

script-src exemple1.local exemple2.local

Si vous n’avez pas besoin de certains types de contenu pour une page ou pour l’ensemble du site Internet, vous pouvez alors entrer la valeur 'none'  dans l’en-tête des di­rec­tives cor­res­pon­dantes, vous spécifiez ainsi qu’aucune source ne peut être chargée du tout. Vous pouvez aussi utiliser la valeur 'self' pour spécifier que le na­vi­ga­teur ne peut charger que du contenu provenant de la même source. Les deux valeurs doivent toujours être écrites entre guil­le­mets simples, sinon none et self seront in­ter­pré­tés comme des domaines.

Il existe dif­fé­rentes options d’en-tête pour définir une Content Security Policy :

  • Content Security Policy
  • X-Webkit CSP
  • X-Content Security Policy

Tous les na­vi­ga­teurs ne sup­por­tent pas tous les noms. Cependant, le W3C (l’organisme de stan­dar­di­sa­tion sur le Web) propose une Content-Security-Policy. Par con­sé­quent, tous les na­vi­ga­teurs modernes se sont adaptés à ce standard de sécurité (les deux autres versions sont con­si­dé­rés comme obsolètes). Pour vous assurer d’atteindre le plus grand nombre possible d’in­ter­nautes (même ceux dont la version du na­vi­ga­teur est dépassée) avec votre CSP, il est re­com­mandé d’inclure tous les champs d’en-tête. Si un na­vi­ga­teur Web ne peut pas utiliser l’en-tête Content Security Policy, il l’ignorera sim­ple­ment et affichera le site Web sans problème, cependant, la pro­tec­tion sup­plé­men­taire n’est pas fournie aux uti­li­sa­teurs concernés.

Vous dé­fi­nis­sez ha­bi­tuel­le­ment les en-têtes HTTP à travers les pages pour l’ensemble de votre domaine. Pour les sous-ré­per­toires, vous pouvez utiliser le fichier .htaccess. Vous utilisez ensuite le mécanisme de sécurité CSP pour définir des règles spéciales pour des sous-pages in­di­vi­duelles.  Par exemple, si vous avez im­plé­menté un bouton de médias sociaux sur une page mais pas sur la suivante, il est logique de n’autoriser l’accès qu’à la source externe sur la première page.

Les sources peuvent être saisies sous forme d’adresses, à leurs façons ou sous forme de Wildcard (Joker). Les entrées suivantes sont donc au­to­ri­sées :

  • script-src 'https://example.com:443' – Les scripts ne sont autorisés à partir de ce domaine que via HTTPS.
  • script-src 'none' – Les scripts ne doivent pas être chargés.
  • script-src 'self' – Les scripts peuvent être chargés depuis la même source que la page prin­ci­pale, mais pas depuis les sous-domaines.
  • script-src https: – Les scripts peuvent être chargés à partir de n’importe quel domaine tant qu’il débute par HTTPS.
  • script-src example.com – Les scripts peuvent être chargés à partir de ce domaine
  • script-src *.example.com – Les scripts de ce domaine et de tous les sous-domaines sont autorisés.
  • img-src data: – Les images peuvent être chargées via des URL de données

Une Content Security Policy stipule fon­da­men­ta­le­ment que les scripts ne peuvent être chargés qu’à partir de fichiers, et non di­rec­te­ment à partir du code du site Web. Si vous voulez éviter cela, vous pouvez utiliser la commande script-src 'unsafe-inline'. Cependant, vous devez être conscient que cela crée à son tour une faille de sécurité. La norme de sécurité interdit aussi la fonction eval (). En fait, vous pouvez convertir le texte en code Ja­vaS­cript avec cette commande, mais même ceci est un risque de sécurité. Si vous avez encore besoin de cette fonction, vous pouvez la réactiver avec script-src 'unsafe-eval'.

Conseil

vous pouvez sécuriser unsafe-inline avec un détour. Les valeurs de hachage ou la source Nonce comblent cette faille de sécurité.

Si les scripts ne sont plus autorisés à ap­pa­raître di­rec­te­ment dans le code, vous devez créer un fichier séparé pour chaque script. La fonction du script est stockée dans un fichier .js. Seulement s’ils sont ré­fé­ren­cés dans le code du site Web :

<script src='beispiel.js'></script>

Ce que le script fait au final est décrit dans exemple.js. Vous devez aussi stocker les éléments de style dans des feuilles de sytle séparées. Si, en tant que Webmaster, vous souhaitez in­tro­duire un Content Security Policy, il ne suffit pas d‘insérer l’en-tête. Vous devez aussi vérifier et adapter le code source de votre site Web.

Note

vous voulez savoir dans quelle mesure votre propre site Web est sécurisé ? Mozilla apporte un test facile à utiliser : Ob­ser­va­tory by Mozilla qui vous donne un score après un scan et vous indique où et comment rendre votre site plus sûr.

Content Security Policy : un exemple

À l’aide d’un exemple, nous allons main­te­nant vous montrer comment réaliser un en-tête Content Security Policy et expliquer ce qui doit être fait avec l’en-tête.

  • Content-Security-Policy: "default-src 'none'; script-src 'self' *.example.com; style-src 'self'; img-src 'self' data:; font-src 'self' https://fonts.google.com/; report-uri 'https://example.org/report.html';
  • X-Content-Security-Policy: "default-src 'none'; script-src 'self' *.example.com; style-src 'self'; img-src 'self' data:; font-src 'self' https://fonts.google.com/; report-uri 'https://example.org/report.html';
  • X-WebKit-CSP: "default-src 'none'; script-src 'self' *.example.com; style-src 'self'; img-src 'self' data:; font-src 'self' https://fonts.google.com/; report-uri 'https://example.org';

Vous verrez que chaque variante de la CSP apparait dans l’en-tête pour que le plus de na­vi­ga­teurs puissent être adressés. Dans chaque en-tête, le contenu est identique : les sources sont listées l’une après l’autre et les di­rec­tives sont séparées par un point-virgule. La syntaxe est toujours la même. En fait, seul le nom du champ change, de sorte que vous pouvez sim­ple­ment dupliquer le contenu.

Tout d’abord, nous spé­ci­fions que, sauf in­di­ca­tion contraire dans une directive, les données ne doivent pas être chargées à partir d’une source quel­conque (default-src). Cela comble une lacune en matière de sécurité. Vous devez toujours définir default-src en premier. Cela permet d’éviter qu’une directive oubliée ne laisse une lacune dans votre Content Security Policy.

Ensuite, nous dé­fi­nis­sions la source à partir de laquelle les scripts peuvent être chargés (script-src). Dans l’exemple, nous spé­ci­fions que le na­vi­ga­teur ne charge que les scripts provenant de la même source et de example.com avec tous les sous-domaines (vous attribuez le Joker avec *). De plus, nous spé­ci­fions que les clients ne peuvent charger des feuilles de style qu’à partir de leur propre source (style-src). Les images ne sont au­to­ri­sées qu’à partir de leur propre source en tant qu’URL de données (img-src). Selon l’en-tête Content-Security-Policy, les polices ne peuvent être chargées qu‘à partir d’une source et de l’offre de Google. Enfin, dans l’exemple, nous spé­ci­fions un endroit où les messages sont envoyés si quelqu’un tente de violer les normes de sécurité (report-uri).

Vous re­mar­que­rez que nous n’avons pas inclus toutes les di­rec­tives dans l’en-tête. Ce n’est pas du tout un problème : dans le cas présent, nous n’avons pas besoin d’autres listes blanches, et avec default-src, toutes les autres sources sont dé­sac­ti­vées.

Conseil

plusieurs gé­né­ra­teurs de Content-Security-Policy sont dis­po­nibles sur Internet. Avec des offres comme CSP Is Awesome ou Report URI, vous pouvez créer des champs d’en-tête CSP fa­ci­le­ment et de manière fiable.

Aller au menu principal