Content Security Policy

Joe Medley
Joe Medley

Le modèle de sécurité Web utilise la règle de même origine. Le code de https://mybank.com ne devrait avoir accès qu'aux données de https://mybank.com, et https://evil.example.com ne devrait jamais être autorisé à y accéder. Chaque origine est isolée du reste du Web, ce qui offre aux développeurs un bac à sable sécurisé pour créer des applications et jouer. En théorie, c'est parfaitement génial. En pratique, les pirates informatiques ont trouvé des moyens astucieux de renverser le système.

Les attaques de type script intersites (XSS), par exemple, contournent la même règle d'origine en incitant un site à fournir du code malveillant avec le contenu prévu. Il s'agit d'un problème majeur, car les navigateurs font confiance à l'ensemble du code qui apparaît sur une page comme faisant légitimement partie de l'origine de sécurité de cette page. L'aide-mémoire XSS est un aperçu ancien, mais représentatif, des méthodes qu'un pirate informatique peut utiliser pour violer cette confiance en injectant du code malveillant. Si un pirate informatique injecte n'importe quel code, c'est la fin de la partie: les données de session utilisateur sont compromises et les informations qui doivent rester secrètes sont exfiltrées vers The Bad Guys. Nous aimerions évidemment éviter cela, si possible.

Cette présentation met en évidence une défense qui peut réduire considérablement le risque et l'impact des attaques XSS dans les navigateurs modernes: Content Security Policy (CSP).

Résumé

  • Utilisez des listes d'autorisation pour indiquer au client ce qui est autorisé et ce qui ne l'est pas.
  • Découvrez les instructions disponibles.
  • Identifier les mots clés utilisés
  • Le code intégré et eval() sont considérés comme dangereux.
  • Signalez à votre serveur les cas de non-respect des règles avant de les appliquer.

Listes d'autorisation de sources

Le problème exploité par les attaques XSS est l'incapacité du navigateur à faire la distinction entre le script faisant partie de votre application et le script injecté de manière malveillante par un tiers. Par exemple, le bouton +1 de Google situé en bas de cette page charge et exécute le code à partir de https://apis.google.com/js/plusone.js dans le contexte de l'origine de cette page. Nous faisons confiance à ce code, mais nous ne pouvons pas attendre que le navigateur réalise lui-même que le code de apis.google.com est génial, contrairement au code de apis.evil.example.com. Le navigateur télécharge et exécute avec plaisir le code demandé par une page, quelle que soit la source.

Au lieu de faire aveuglément confiance à tout ce qu'un serveur fournit, CSP définit l'en-tête HTTP Content-Security-Policy, ce qui vous permet de créer une liste d'autorisation de sources de contenu fiable et indique au navigateur de n'exécuter ou d'afficher que les ressources provenant de ces sources. Même si un pirate informatique parvient à trouver une faille par laquelle injecter le script, celui-ci ne correspondra pas à la liste d'autorisation et ne sera donc pas exécuté.

Étant donné que nous faisons confiance à apis.google.com pour fournir du code valide et à ce que nous faisons de même, définissons une stratégie qui n'autorise le script à s'exécuter que lorsqu'il provient de l'une de ces deux sources:

Content-Security-Policy: script-src 'self' https://apis.google.com

Simple, n'est-ce pas ? Comme vous l'avez probablement deviné, script-src est une directive qui contrôle un ensemble de droits liés aux scripts pour une page spécifique. Nous avons spécifié 'self' comme source valide de script et https://apis.google.com comme une autre. Le navigateur télécharge et exécute correctement le code JavaScript à partir de apis.google.com via HTTPS, ainsi qu'à partir de l'origine de la page actuelle.

Erreur de console: impossible de charger le script "http://evil.example.com/evil.js", car il ne respecte pas la directive suivante de la Content Security Policy: script-src 'self' https://apis.google.com

Une fois cette règle définie, le navigateur génère simplement une erreur au lieu de charger le script depuis une autre source. Lorsqu'un pirate informatique parvient à injecter du code dans votre site, il reçoit un message d'erreur au lieu d'obtenir le résultat escompté.

Une stratégie s'applique à une grande variété de ressources

Bien que les ressources de script représentent les risques de sécurité les plus évidents, CSP fournit un ensemble complet de directives de stratégie qui permet un contrôle assez précis sur les ressources qu'une page est autorisée à charger. Comme vous avez déjà vu script-src, le concept doit être clair.

Examinons rapidement le reste des directives de ressources. La liste ci-dessous représente l'état des directives au niveau 2. Une spécification de niveau 3 a été publiée, mais elle n'est en grande partie pas implémentée dans les principaux navigateurs.

  • base-uri limite les URL pouvant apparaître dans l'élément <base> d'une page.
  • child-src liste les URL des workers et du contenu des cadres intégrés. Par exemple, child-src https://youtube.com permet d'intégrer des vidéos provenant de YouTube, mais pas d'autres origines.
  • connect-src limite les origines auxquelles vous pouvez vous connecter (via XHR, WebSockets et EventSource).
  • font-src spécifie les origines qui peuvent diffuser des polices Web. Les polices Web de Google peuvent être activées via font-src https://themes.googleusercontent.com.
  • form-action liste les points de terminaison valides pour l'envoi à partir des balises <form>.
  • frame-ancestors spécifie les sources autorisées à intégrer la page actuelle. Cette directive s'applique aux balises <frame>, <iframe>, <embed> et <applet>. Cette instruction ne peut pas être utilisée dans les tags <meta> et ne s'applique qu'aux ressources non HTML.
  • frame-src a été abandonné au niveau 2, mais a été restauré au niveau 3. Si ce n'est pas le cas, la valeur child-src est utilisée comme précédemment.
  • img-src définit les origines à partir desquelles les images peuvent être chargées.
  • media-src limite les origines autorisées à diffuser de la vidéo et de l'audio.
  • object-src permet de contrôler Flash et les autres plug-ins.
  • plugin-types limite les types de plug-ins qu'une page peut appeler.
  • report-uri spécifie l'URL à laquelle un navigateur envoie un rapport en cas de non-respect d'une règle de sécurité du contenu. Cette instruction ne peut pas être utilisée dans les balises <meta>.
  • style-src est l'équivalent de script-src pour les feuilles de style.
  • upgrade-insecure-requests demande aux user-agents de réécrire les schémas d'URL en remplaçant HTTP par HTTPS. Cette directive est destinée aux sites Web comportant un grand nombre d'anciennes URL devant être réécrites.
  • worker-src est une directive CSP de niveau 3 qui restreint les URL pouvant être chargées en tant que worker, worker partagé ou service worker. Depuis juillet 2017, cette directive comporte des implémentations limitées.

Par défaut, les directives sont larges. Si vous ne définissez pas de règle spécifique pour une instruction (par exemple, font-src), cette instruction se comporte par défaut comme si vous aviez spécifié * comme source valide (par exemple, vous pouvez charger des polices depuis n'importe quel emplacement, sans restriction).

Vous pouvez ignorer ce comportement par défaut en spécifiant une instruction default-src. Cette directive définit les valeurs par défaut pour la plupart des instructions que vous ne spécifiez pas. En règle générale, cela s'applique à toute instruction qui se termine par -src. Si default-src est défini sur https://example.com et que vous ne spécifiez pas d'instruction font-src, vous pouvez charger des polices à partir de https://example.com, et nulle part ailleurs. Nous n'avons spécifié que script-src dans les exemples précédents, ce qui signifie que les images, les polices, etc. peuvent être chargées à partir de n'importe quelle origine.

Les instructions suivantes n'utilisent pas default-src comme solution de secours. N'oubliez pas que ne pas les définir revient à autoriser quoi que ce soit.

  • base-uri
  • form-action
  • frame-ancestors
  • plugin-types
  • report-uri
  • sandbox

Vous pouvez utiliser autant d'instructions que nécessaire pour votre application, en les répertoriant simplement dans l'en-tête HTTP, en les séparant par un point-virgule. Veillez à répertorier toutes les ressources requises d'un type spécifique dans une seule directive. Si vous écrivez un élément tel que script-src https://host1.com; script-src https://host2.com, la deuxième instruction sera simplement ignorée. Un élément semblable à ce qui suit spécifierait correctement les deux origines comme valides:

script-src https://host1.com https://host2.com

Par exemple, si votre application charge toutes ses ressources à partir d'un réseau de diffusion de contenu (par exemple, https://cdn.example.net) et que vous savez que vous n'avez pas besoin de contenu encadré ni de plug-ins, votre règle peut se présenter comme suit:

Content-Security-Policy: default-src https://cdn.example.net; child-src 'none'; object-src 'none'

Détails de mise en œuvre

Vous verrez les en-têtes X-WebKit-CSP et X-Content-Security-Policy dans différents tutoriels sur le Web. À l'avenir, vous devriez ignorer ces en-têtes préfixés. Les navigateurs récents (à l'exception d'IE) sont compatibles avec l'en-tête Content-Security-Policy sans préfixe. C'est l'en-tête à utiliser.

Quel que soit l'en-tête que vous utilisez, la règle est définie page par page : vous devez envoyer l'en-tête HTTP avec chaque réponse dont vous souhaitez vous assurer qu'elle est protégée. Vous bénéficiez ainsi d'une grande flexibilité, car vous pouvez affiner la stratégie pour des pages spécifiques en fonction de leurs besoins spécifiques. Il se peut qu'un ensemble de pages de votre site comporte un bouton +1, mais pas d'autres: vous pouvez autoriser le chargement du code du bouton uniquement lorsque cela est nécessaire.

La liste des sources dans chaque directive est flexible. Vous pouvez spécifier les sources par schéma (data:, https:), ou par niveau de spécificité allant de nom d'hôte uniquement (example.com, qui correspond à n'importe quelle origine sur cet hôte, n'importe quel schéma, n'importe quel port) à un URI complet (https://example.com:443, qui correspond uniquement à HTTPS, uniquement example.com et uniquement le port 443). Les caractères génériques sont acceptés, mais uniquement en tant que schéma, port ou à la position la plus à gauche du nom d'hôte: *://*.example.com:* correspond à tous les sous-domaines de example.com (mais pas à example.com lui-même), à l'aide de n'importe quel schéma et sur n'importe quel port.

La liste de sources accepte également quatre mots clés:

  • Comme prévu, 'none' ne correspond à rien.
  • 'self' correspond à l'origine actuelle, mais pas à ses sous-domaines.
  • 'unsafe-inline' autorise les fichiers JavaScript et CSS intégrés. (Nous y reviendrons plus en détail dans quelques instants.)
  • 'unsafe-eval' autorise les mécanismes texte-vers-JavaScript comme eval. (Nous y reviendrons également.)

Ces mots clés doivent être entourés de guillemets simples. Par exemple, script-src 'self' (entre guillemets) autorise l'exécution de JavaScript à partir de l'hôte actuel. script-src self (sans guillemets) autorise l'exécution de JavaScript depuis un serveur nommé "self" (et non de l'hôte actuel), ce que vous n'avez probablement pas voulu dire.

Bac à sable

Il existe une autre directive qui mérite d'être abordée: sandbox. Il est un peu différent des autres que nous avons examinés, car il impose des restrictions sur les actions qu'une page peut effectuer plutôt que sur les ressources qu'elle peut charger. Si l'instruction sandbox est présente, la page est traitée comme si elle avait été chargée dans un <iframe> avec un attribut sandbox. Cela peut avoir de nombreux effets sur la page, y compris forcer la page à une origine unique et empêcher l'envoi de formulaires. Cet article dépasse le cadre de cet article, mais vous trouverez tous les détails sur les attributs de bac à sable valides dans la section "Sandbox" de la spécification HTML5.

La balise Meta

Le mécanisme de diffusion préféré des CSP est un en-tête HTTP. Il peut toutefois être utile de définir une règle sur une page directement dans le balisage. Pour ce faire, utilisez une balise <meta> avec un attribut http-equiv:

<meta
  http-equiv="Content-Security-Policy"
  content="default-src https://cdn.example.net; child-src 'none'; object-src 'none'"
/>

Impossible d'utiliser frame-ancestors, report-uri ou sandbox.

Le code intégré est considéré comme dangereux

Il doit être clair que CSP est basé sur des origines de liste d'autorisation, car il s'agit d'une manière claire de demander au navigateur de traiter des ensembles spécifiques de ressources comme acceptables et de refuser le reste. Toutefois, les listes d'autorisation basées sur l'origine ne résolvent pas la plus grande menace des attaques XSS: l'injection de script intégré. Si un pirate informatique parvient à injecter un tag de script contenant directement une charge utile malveillante (<script>sendMyDataToEvilDotCom();</script>), le navigateur ne dispose d'aucun mécanisme permettant de le distinguer d'un tag de script intégré légitime. CSP résout ce problème en interdisant complètement les scripts intégrés : c'est le seul moyen d'en être sûr.

Cette interdiction concerne non seulement les scripts intégrés directement dans les balises script, mais également les gestionnaires d'événements intégrés et les URL javascript:. Vous devez déplacer le contenu des balises script dans un fichier externe, et remplacer les URL javascript: et <a ... onclick="[JAVASCRIPT]"> par les appels addEventListener() appropriés. Par exemple, vous pouvez réécrire ce qui suit à partir de:

<script>
  function doAmazingThings() {
    alert('YOU AM AMAZING!');
  }
</script>
<button onclick="doAmazingThings();">Am I amazing?</button>

par quelque chose de plus comme:

<!-- amazing.html -->
<script src="amazing.js"></script>
<button id="amazing">Am I amazing?</button>

<div style="clear:both;"></div>
// amazing.js
function doAmazingThings() {
  alert('YOU AM AMAZING!');
}
document.addEventListener('DOMContentLoaded', function () {
  document.getElementById('amazing').addEventListener('click', doAmazingThings);
});

Le code réécrit présente de nombreux avantages, en plus de fonctionner correctement avec CSP. C'est déjà une bonne pratique, quelle que soit votre utilisation de CSP. Le JavaScript intégré combine structure et comportement exactement comme vous ne le feriez pas. Les ressources externes sont plus faciles à mettre en cache pour les navigateurs, plus compréhensibles pour les développeurs, et favorisent la compilation et la minimisation. Vous obtiendrez un meilleur code si vous faites le travail pour déplacer le code vers des ressources externes.

Le style intégré est traité de la même manière: l'attribut style et les balises style doivent être regroupés dans des feuilles de style externes afin de se protéger contre diverses méthodes d'exfiltration de données étonnamment intelligentes activées par le CSS.

Si vous devez disposer d'un script et d'un style intégrés, vous pouvez les activer en ajoutant 'unsafe-inline' en tant que source autorisée dans une directive script-src ou style-src. Vous pouvez également utiliser un nonce ou un hachage (voir ci-dessous), mais ce n'est pas conseillé. L'exclusion des scripts intégrés est la plus grande amélioration de la sécurité fournie par CSP, et bannir les styles intégrés renforce également votre application. Après avoir mis l'ensemble du code hors ligne, la mise en œuvre d'un processus correct demande un peu d'efforts en amont, mais le compromis mérite d'être réalisé.

Si vous devez absolument l'utiliser

CSP niveau 2 offre une rétrocompatibilité pour les scripts intégrés en vous permettant d'ajouter des scripts intégrés spécifiques à la liste d'autorisation à l'aide d'un nonce cryptographique (nombre utilisé une fois) ou d'un hachage. Bien que cela puisse être fastidieux, il est utile à un pincement.

Pour utiliser un nonce, attribuez un attribut nonce à votre balise de script. Sa valeur doit correspondre à l'une des sources de confiance de la liste. Exemple :

<script nonce="EDNnf03nceIOfn39fn3e9h3sdfa">
  // Some inline code I can't remove yet, but need to asap.
</script>

Ajoutez maintenant le nonce à votre directive script-src ajoutée au mot clé nonce-.

Content-Security-Policy: script-src 'nonce-EDNnf03nceIOfn39fn3e9h3sdfa'

N'oubliez pas que les nonces doivent être générés de nouveau pour chaque requête de page et qu'ils ne doivent pas être devinés.

Les hachages fonctionnent à peu près de la même manière. Au lieu d'ajouter du code au tag de script, créez un hachage SHA du script lui-même et ajoutez-le à la directive script-src. Par exemple, imaginons que votre page contienne le code suivant:

<script>
  alert('Hello, world.');
</script>

Votre stratégie contiendrait le texte suivant:

Content-Security-Policy: script-src 'sha256-qznLcsROx4GACP2dm0UCKCzCG-HiZ1guq6ZZDob_Tng='

Voici quelques points à noter. Le préfixe sha*- spécifie l'algorithme qui génère le hachage. Dans l'exemple ci-dessus, sha256- est utilisé. CSP est également compatible avec sha384- et sha512-. N'incluez pas les balises <script> lorsque vous générez le hachage. La casse et les espaces blancs sont également pris en compte, y compris les espaces de début ou de fin.

Une recherche Google sur la génération de hachages SHA vous mènera à des solutions dans autant de langues que vous le souhaitez. À l'aide de Chrome 40 ou d'une version ultérieure, vous pouvez ouvrir les outils de développement, puis actualiser votre page. L'onglet "Console" contient des messages d'erreur avec le hachage sha256 correct pour chacun de vos scripts intégrés.

Effectuez également une évaluation

Même lorsqu'un pirate informatique ne peut pas injecter directement de script, il peut tromper votre application et l'inciter à convertir du texte inerte en JavaScript exécutable et à l'exécuter en son nom. eval(), new Function(), setTimeout([string], ...) et setInterval([string], ...) sont tous des vecteurs par lesquels le texte injecté peut entraîner l'exécution d'un événement malveillant inattendu. La réponse par défaut de la CSP à ce risque consiste à bloquer complètement tous ces vecteurs.

Cela a plus de quelques répercussions sur la façon dont vous créez des applications:

  • Vous devez analyser le format JSON via la classe JSON.parse intégrée, plutôt que d'utiliser eval. Les opérations JSON natives sont disponibles dans tous les navigateurs depuis IE8 et entièrement sécurisées.
  • Réécrivez tous les appels setTimeout ou setInterval que vous effectuez actuellement avec des fonctions intégrées plutôt qu'avec des chaînes. Exemple :
setTimeout("document.querySelector('a').style.display = 'none';", 10);

serait mieux rédigée comme suit:

setTimeout(function () {
  document.querySelector('a').style.display = 'none';
}, 10);
  • Évitez la création de modèles intégrés au moment de l'exécution: de nombreuses bibliothèques de modèles utilisent généreusement new Function() pour accélérer la génération des modèles au moment de l'exécution. Il s'agit d'une application astucieuse de la programmation dynamique, au risque d'évaluer du texte malveillant. Certains frameworks prennent en charge CSP par défaut et recourent à un analyseur robuste en l'absence de eval. La directive ng-csp d'AngularJS en est un bon exemple.

Toutefois, il est préférable d'utiliser un langage de création de modèles qui propose une précompilation (par exemple, Handlebars). La précompilation de vos modèles peut rendre l'expérience utilisateur encore plus rapide que l'implémentation d'exécution la plus rapide, et elle est également plus sûre. Si l'évaluation et ses composants texte-vers-JavaScript sont essentiels pour votre application, vous pouvez les activer en ajoutant 'unsafe-eval' en tant que source autorisée dans une directive script-src, mais nous vous le déconseillons vivement. Lorsque vous interdisez la possibilité d'exécuter des chaînes, il est beaucoup plus difficile pour un pirate informatique d'exécuter du code non autorisé sur votre site.

Reporting

La capacité de CSP à bloquer les ressources non approuvées côté client est une grande victoire pour vos utilisateurs, mais il serait très utile de renvoyer une sorte de notification au serveur afin de pouvoir identifier et éliminer tous les bugs qui autorisent une injection malveillante en premier lieu. À cette fin, vous pouvez demander au navigateur de POST signaler les cas de non-respect au format JSON vers un emplacement spécifié dans une directive report-uri.

Content-Security-Policy: default-src 'self'; ...; report-uri /my_amazing_csp_report_parser;

Ces rapports se présentent comme suit:

{
  "csp-report": {
    "document-uri": "http://example.org/page.html",
    "referrer": "http://evil.example.com/",
    "blocked-uri": "http://evil.example.com/evil.js",
    "violated-directive": "script-src 'self' https://apis.google.com",
    "original-policy": "script-src 'self' https://apis.google.com; report-uri http://example.org/my_amazing_csp_report_parser"
  }
}

Il contient un bon nombre d'informations qui vous aideront à identifier la cause spécifique du non-respect, y compris la page concernée (document-uri), l'URL de provenance de cette page (notez que contrairement au champ d'en-tête HTTP, la clé n'est pas mal orthographiée), la ressource qui a enfreint la règle de la page (blocked-uri), l'instruction spécifique enfreinte (violated-directive) et la règle complète de la page (original-policy).

Rapport uniquement

Si vous débutez avec CSP, il est judicieux d'évaluer l'état actuel de votre application avant de déployer une règle draconienne auprès de vos utilisateurs. Pour entamer un déploiement complet, vous pouvez demander au navigateur de surveiller une règle, de signaler les cas de non-respect sans appliquer les restrictions. Au lieu d'envoyer un en-tête Content-Security-Policy, envoyez un en-tête Content-Security-Policy-Report-Only.

Content-Security-Policy-Report-Only: default-src 'self'; ...; report-uri /my_amazing_csp_report_parser;

La règle spécifiée en mode Rapport uniquement ne bloque pas les ressources limitées, mais envoie des rapports de cas de non-respect à l'emplacement que vous spécifiez. Vous pouvez même envoyer les deux en-têtes, en appliquant une règle tout en surveillant une autre. C'est un excellent moyen d'évaluer l'effet des modifications apportées au CSP de votre application: activez la création de rapports pour une nouvelle règle, surveillez les signalements d'infractions et corrigez les bugs éventuels. Une fois que vous êtes satisfait de son effet, commencez à appliquer la nouvelle règle.

Utilisation dans le monde réel

CSP 1 est assez utilisable dans Chrome, Safari et Firefox, mais sa compatibilité avec IE 10 est très limitée. Vous pouvez consulter les détails sur caniuse.com. CSP niveau 2 est disponible dans Chrome depuis la version 40. Des sites très importants comme Twitter et Facebook ont déployé l'en-tête (l'étude de cas de Twitter mérite d'être consultée), et la norme est prête à être déployée sur vos propres sites.

Pour élaborer une stratégie pour votre application, la première étape consiste à évaluer les ressources que vous chargez réellement. Une fois que vous pensez maîtriser la façon dont les éléments sont organisés dans votre application, configurez une règle basée sur ces exigences. Examinons quelques cas d'utilisation courants et déterminons la meilleure façon de les prendre en charge dans les confins de protection de CSP.

Cas d'utilisation n° 1: widgets de réseaux sociaux

  • Le bouton +1 de Google inclut un script de https://apis.google.com et intègre un <iframe> de https://plusone.google.com. Vous avez besoin d'une règle qui inclut ces deux origines pour intégrer le bouton. Une règle minimale est script-src https://apis.google.com; child-src https://plusone.google.com. Vous devez également vous assurer que l'extrait de code JavaScript fourni par Google est extrait dans un fichier JavaScript externe. Si vous aviez une règle basée sur le niveau 1 utilisant frame-src, le niveau 2 exigeait de la remplacer par child-src. Cela n'est plus nécessaire au niveau 3 de CSP.

  • Le bouton Like (J'aime) de Facebook propose plusieurs options d'implémentation. Nous vous recommandons de vous en tenir à la version <iframe>, car elle est isolée du reste de votre site dans le bac à sable. Une instruction child-src https://facebook.com est nécessaire pour fonctionner correctement. Notez que, par défaut, le code <iframe> fourni par Facebook charge une URL relative, //facebook.com. Modifiez ce paramètre pour spécifier explicitement HTTPS : https://facebook.com. Le protocole HTTP n'a aucune raison d'être utilisé si ce n'est pas nécessaire.

  • Le bouton Tweet de Twitter dépend de l'accès à un script et à un frame, tous deux hébergés sur https://platform.twitter.com. (Twitter fournit également une URL relative par défaut ; modifiez le code pour spécifier HTTPS lorsque vous le copiez/collez localement). Vous êtes alors configuré avec script-src https://platform.twitter.com; child-src https://platform.twitter.com, tant que vous déplacez l'extrait de code JavaScript fourni par Twitter dans un fichier JavaScript externe.

  • Les autres plates-formes ont des exigences similaires et peuvent être traitées de la même manière. Nous vous suggérons de simplement définir un default-src sur 'none' et de surveiller votre console pour déterminer les ressources que vous devez activer pour que les widgets fonctionnent.

L'inclusion de plusieurs widgets est simple: il vous suffit de combiner les instructions des règles, sans oublier de fusionner toutes les ressources d'un même type en une seule. Si vous souhaitez utiliser les trois widgets de réseaux sociaux, la règle se présentera comme suit:

script-src https://apis.google.com https://platform.twitter.com; child-src https://plusone.google.com https://facebook.com https://platform.twitter.com

Cas d'utilisation n° 2: verrouillage

Supposons que vous gériez un site bancaire et que vous souhaitiez vous assurer que seules les ressources que vous avez écrites vous-même peuvent être chargées. Dans ce scénario, commencez avec une stratégie par défaut qui bloque absolument tout (default-src 'none'), puis créez-la à partir de là.

Supposons que la banque charge toutes les images, tous les styles et tous les scripts à partir d'un CDN à l'emplacement https://cdn.mybank.net, et se connecte via XHR à https://api.mybank.com/ pour extraire différents bits de données. Les cadres sont utilisés, mais uniquement pour les pages locales du site (pas d'origines tierces). Il n'y a pas de flash sur le site, pas de polices, pas d'extras. L'en-tête CSP le plus restrictif que nous puissions envoyer est le suivant:

Content-Security-Policy: default-src 'none'; script-src https://cdn.mybank.net; style-src https://cdn.mybank.net; img-src https://cdn.mybank.net; connect-src https://api.mybank.com; child-src 'self'

Cas d'utilisation n° 3: SSL uniquement

Un administrateur d'un forum de discussion sur l'alliance veut s'assurer que toutes les ressources sont uniquement chargées via des canaux sécurisés, mais il n'écrit pas vraiment beaucoup de code. Il ne peut pas non plus réécrire de vastes parties du logiciel de forum tiers remplies de script et de style intégrés. La règle suivante serait efficace:

Content-Security-Policy: default-src https:; script-src https: 'unsafe-inline'; style-src https: 'unsafe-inline'

Même si https: est spécifié dans default-src, les instructions de script et de style n'héritent pas automatiquement de cette source. Chaque instruction écrase complètement la valeur par défaut de ce type de ressource spécifique.

L'avenir

Content Security Policy niveau 2 est une recommandation candidate. Le groupe de travail du W3C sur la sécurité des applications Web a déjà commencé à travailler sur la prochaine itération de la spécification, Content Security Policy Level 3.

Si vous êtes intéressé par la discussion sur ces fonctionnalités à venir, parcourez les archives de la liste de diffusion public-webappsec@ ou participez-y.

Commentaires