Content Security Policy

Joe Medley
Joe Medley

Le modèle de sécurité du Web repose sur le Règlement d'origine identique. Le code de https://mybank.com ne doit avoir accès qu'aux données de https://mybank.com, et https://evil.example.com ne doit jamais y avoir accès. Chaque origine est isolée du reste du Web, ce qui offre aux développeurs un bac à sable sécurisé dans lequel créer et jouer. En théorie, c'est tout à fait génial. En pratique, les pirates informatiques ont trouvé des moyens astucieux de subvertir le système.

Les attaques de script intersites (XSS), par exemple, contournent la règle de même origine en incitant un site à diffuser du code malveillant avec le contenu prévu. Il s'agit d'un problème majeur, car les navigateurs font confiance à tout le code qui s'affiche sur une page comme faisant légitimement partie de l'origine de sécurité de cette page. La fiche récapitulative sur les XSS est une ancienne section transversale, mais représentative, des méthodes qu'un pirate informatique peut utiliser pour enfreindre cette confiance en injectant du code malveillant. Si un pirate informatique parvient à injecter n'importe quel code, c'est pratiquement la fin du jeu: les données de session utilisateur sont compromises et les informations qui doivent rester secrètes sont exfiltrées vers les pirates informatiques. Nous aimerions bien éviter cela, si possible.

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

TL;DR

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

Listes d'autorisation sources

Le problème exploité par les attaques XSS est l'incapacité du navigateur à distinguer le script qui fait partie de votre application du script qui a été injecté de manière malveillante par un tiers. Par exemple, le bouton Google +1 en bas de cette page charge et exécute le code 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 nous attendre à ce que le navigateur détermine lui-même que le code de apis.google.com est génial, tandis que celui de apis.evil.example.com ne l'est probablement pas. Le navigateur télécharge et exécute sans problème tout code qu'une page demande, quelle que soit la source.

Au lieu de faire aveuglément confiance à tout ce qu'un serveur fournit, la CSP définit l'en-tête HTTP Content-Security-Policy, qui vous permet de créer une liste d'autorisation des sources de contenu fiables, puis demande au navigateur de n'exécuter ou d'afficher que des ressources provenant de ces sources. Même si un pirate informatique peut trouver une faille par laquelle injecter un script, le script 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 que nous nous faisons confiance pour faire de même, définissons une stratégie qui n'autorise l'exécution du script 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 de script valide et https://apis.google.com comme autre source. Le navigateur télécharge et exécute correctement le code JavaScript à partir de apis.google.com via HTTPS, ainsi que depuis l'origine de la page actuelle.

Erreur de console: le chargement du script "http://evil.example.com/evil.js" a été refusé, car il ne respecte pas la directive de la Content Security Policy suivante: 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 à partir de toute autre source. Lorsqu'un pirate informatique astucieux parvient à injecter du code dans votre site, il se heurte à un message d'erreur plutôt qu'au succès qu'il attendait.

La stratégie s'applique à un large éventail de ressources

Bien que les ressources de script soient les risques de sécurité les plus évidents, le CSP fournit un ensemble riche de directives de stratégie qui permettent un contrôle assez précis des ressources qu'une page est autorisée à charger. Vous avez déjà vu script-src, le concept devrait donc être clair.

Passons rapidement en revue 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 largement 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 nœuds de calcul et les contenus des cadres intégrés. Par exemple, child-src https://youtube.com permet d'intégrer des vidéos YouTube, mais pas d'autres sources.
  • connect-src limite les origines auxquelles vous pouvez vous connecter (via XHR, WebSockets et EventSource).
  • font-src spécifie les origines pouvant 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 à envoyer à partir des balises <form>.
  • frame-ancestors spécifie les sources pouvant intégrer la page actuelle. Cette directive s'applique aux balises <frame>, <iframe>, <embed> et <applet>. Cette directive ne peut pas être utilisée dans les balises <meta> et ne s'applique qu'aux ressources autres que HTML.
  • frame-src a été abandonné au niveau 2, mais a été rétabli au niveau 3. Si elle n'est pas présente, child-src est toujours utilisé, comme auparavant.
  • img-src définit les origines à partir desquelles les images peuvent être chargées.
  • media-src limite les origines autorisées à diffuser des contenus vidéo et audio.
  • object-src permet de contrôler Flash et d'autres plug-ins.
  • plugin-types limite les types de plug-ins qu'une page peut appeler.
  • report-uri spécifie une URL à laquelle un navigateur enverra des rapports en cas de non-respect d'une règle de sécurité du contenu. Cette directive 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 indique aux user-agents de réécrire les schémas d'URL, en remplaçant HTTP par HTTPS. Cette directive s'applique aux sites Web comportant un grand nombre d'anciennes URL à réécrire.
  • worker-src est une directive CSP de niveau 3 qui limite les URL pouvant être chargées en tant que nœud de calcul, nœud de calcul partagé ou service de nœud de calcul. Depuis juillet 2017, cette directive a des implémentations limitées.

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

Vous pouvez ignorer ce comportement par défaut en spécifiant une directive default-src. Cette directive définit les valeurs par défaut pour la plupart des directives que vous laissez non spécifiées. En règle générale, cela s'applique à toute directive se terminant par -src. Si default-src est défini sur https://example.com et que vous ne spécifiez pas de directive 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 nos exemples précédents, ce qui signifie que les images, les polices, etc. peuvent être chargées à partir de n'importe quelle origine.

Les directives suivantes n'utilisent pas default-src comme solution de remplacement. N'oubliez pas que ne pas les définir revient à autoriser tout.

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

Vous pouvez utiliser autant de ces directives que nécessaire pour votre application spécifique, en les listant simplement dans l'en-tête HTTP, en les séparant par des points-virgules. Assurez-vous de lister toutes les ressources requises d'un type spécifique dans une seule directive. Si vous écrivez quelque chose comme script-src https://host1.com; script-src https://host2.com, la deuxième directive sera simplement ignorée. Un code comme celui-ci spécifierait correctement les deux origines comme valides:

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

Par exemple, si vous disposez d'une application qui 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 ni de plug-in encadrés, 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 des en-têtes X-WebKit-CSP et X-Content-Security-Policy dans divers tutoriels sur le Web. À l'avenir, vous devez ignorer ces en-têtes avec préfixe. Les navigateurs modernes (à l'exception d'IE) sont compatibles avec l'en-tête Content-Security-Policy sans préfixe. C'est l'en-tête que vous devez 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 que vous souhaitez protéger. Cela offre une grande flexibilité, car vous pouvez affiner la règle pour des pages spécifiques en fonction de leurs besoins spécifiques. Il est possible qu'un ensemble de pages de votre site comporte un bouton +1, tandis que d'autres n'en comportent pas. Vous pouvez autoriser le code du bouton à être chargé uniquement lorsque cela est nécessaire.

La liste des sources de chaque directive est flexible. Vous pouvez spécifier des sources par schéma (data:, https:), ou en fonction de leur spécificité, de l'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 ne correspond qu'à HTTPS, qu'à example.com et qu'au 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, sur n'importe quel port.

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

  • Comme vous pouvez vous en douter, 'none' ne correspond à rien.
  • 'self' correspond à l'origine actuelle, mais pas à ses sous-domaines.
  • 'unsafe-inline' permet d'intégrer JavaScript et CSS. (Nous y reviendrons plus en détail dans un instant.)
  • 'unsafe-eval' permet d'utiliser des mécanismes de conversion texte-JavaScript tels que eval. (Nous y reviendrons également.)

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

Bac à sable

Il existe une autre directive qui mérite d'être mentionnée: sandbox. Il est un peu différent des autres que nous avons examinés, car il impose des restrictions sur les actions que la page peut effectuer plutôt que sur les ressources qu'elle peut charger. Si la directive 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: forcer la page à avoir une origine unique et empêcher l'envoi du formulaire, par exemple. Cela dépasse un peu le cadre de cet article, mais vous trouverez des informations complètes sur les attributs de bac à sable valides dans la section "Bac à sable" de la spécification HTML5.

La balise Meta

Le mécanisme de diffusion privilégié des CSP est un en-tête HTTP. Toutefois, il peut ê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'"
/>

Cette option ne peut pas être utilisée pour frame-ancestors, report-uri ou sandbox.

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

Il est clair que le CSP est basé sur des origines de liste d'autorisation, car il s'agit d'un moyen sans ambiguïté d'indiquer au navigateur de traiter des ensembles spécifiques de ressources comme acceptables et de rejeter le reste. Toutefois, les listes d'autorisation basées sur l'origine ne résolvent pas la plus grande menace posée par les attaques XSS: l'injection de script en ligne. Si un pirate informatique peut injecter une balise de script contenant directement une charge utile malveillante (<script>sendMyDataToEvilDotCom();</script>), le navigateur ne dispose d'aucun mécanisme pour la distinguer d'une balise de script intégrée légitime. Le CSP résout ce problème en interdisant complètement le script intégré. C'est le seul moyen d'être sûr.

Cette interdiction inclut 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 devrez déplacer le contenu des balises script dans un fichier externe et remplacer les URL javascript: et <a ... onclick="[JAVASCRIPT]"> par des appels addEventListener() appropriés. Par exemple, vous pouvez réécrire le code suivant à partir de:

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

à quelque chose 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 un certain nombre d'avantages en plus de fonctionner correctement avec le CSP. Il s'agit déjà d'une bonne pratique, quel que soit votre utilisation du CSP. Le code JavaScript intégré mélange structure et comportement exactement de la manière dont vous ne devriez pas le faire. Les ressources externes sont plus faciles à mettre en cache pour les navigateurs, plus compréhensibles pour les développeurs et propices à la compilation et à la minification. Vous écrirez un meilleur code si vous effectuez le travail de transfert du 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 pour vous protéger contre diverses méthodes d'exfiltration de données étonnantement intelligentes que le CSS permet.

Si vous devez utiliser un script et 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 vous ne devriez pas. L'interdiction des scripts intégrés est le plus grand avantage de sécurité que le CSP offre. L'interdiction des styles intégrés renforce également votre application. Il faut un peu d'effort au départ pour s'assurer que tout fonctionne correctement après avoir déplacé tout le code hors ligne, mais c'est un compromis qui vaut la peine.

Si vous devez absolument l'utiliser

Le niveau 2 du CSP 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 seule fois) ou d'un hachage. Bien que cela puisse être lourd, cela peut s'avérer utile dans un cas de force majeure.

Pour utiliser un nonce, attribuez un attribut nonce à votre balise de script. Sa valeur doit correspondre à l'une des sources approuvées 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 régénérés pour chaque requête de page et qu'ils doivent être impossibles à deviner.

Les hachages fonctionnent de la même manière. Au lieu d'ajouter du code à la balise 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 ce code:

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

Votre règle doit se présenter comme suit:

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é. Le CSP est également compatible avec sha384- et sha512-. Lors de la génération du hachage, n'incluez pas les balises <script>. La capitalisation et les espaces blancs, y compris les espaces de début ou de fin, sont également importants.

Une recherche Google sur la génération de hachages SHA vous permettra de trouver des solutions dans un grand nombre de langues. Avec Chrome 40 ou version ultérieure, vous pouvez ouvrir les outils pour les développeurs, 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.

Évaluation également

Même si un pirate informatique ne peut pas injecter de script directement, il peut être en mesure de duper votre application pour qu'elle convertisse un texte autrement inerte en code JavaScript exécutable et l'exécute en son nom. eval(), newFunction() , setTimeout([string], ...) et setInterval([string], ...) sont tous des vecteurs par lesquels le texte injecté peut finir par exécuter quelque chose de malveillant de manière inattendue. La réponse par défaut du CSP à ce risque consiste à bloquer complètement tous ces vecteurs.

Cela a de nombreuses conséquences sur la façon dont vous créez des applications:

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

Il est préférable de l'écrire comme suit:

setTimeout(function () {
  document.querySelector('a').style.display = 'none';
}, 10);
  • Évitez l'utilisation de modèles intégrés au moment de l'exécution: de nombreuses bibliothèques de modèles utilisent new Function() de manière excessive pour accélérer la génération de modèles au moment de l'exécution. Il s'agit d'une application pratique de la programmation dynamique, mais elle comporte le risque d'évaluer du texte malveillant. Certains frameworks sont compatibles avec le CSP dès le départ, et reviennent à un analyseur robuste en l'absence de eval. La directive ng-csp d'AngularJS en est un bon exemple.

Toutefois, un meilleur choix serait un langage de création de modèles qui propose une précompilation (Handlebars, par exemple). 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 c'est aussi plus sûr. Si eval et ses frères de conversion texte-JavaScript sont essentiels à votre application, vous pouvez les activer en ajoutant 'unsafe-eval' en tant que source autorisée dans une directive script-src, mais nous vous déconseillons vivement de le faire. En interdisant l'exécution de chaînes, un pirate informatique aura beaucoup plus de difficultés à exécuter du code non autorisé sur votre site.

Rapports

La capacité du CSP à bloquer les ressources non approuvées côté client est un avantage considérable pour vos utilisateurs. Toutefois, il serait très utile de renvoyer une sorte de notification au serveur afin que vous puissiez identifier et corriger les bugs qui permettent une injection malveillante. Pour ce faire, vous pouvez demander au navigateur d'POST envoyer les rapports de non-respect au format JSON à 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 une bonne partie d'informations qui vous aideront à identifier la cause spécifique du non-respect, y compris la page sur laquelle le non-respect s'est produit (document-uri), le référent de cette page (notez que contrairement au champ d'en-tête HTTP, la clé n'est pas mal orthographiée), la ressource qui ne respecte pas le règlement de la page (blocked-uri), la directive spécifique qu'elle ne respecte pas (violated-directive) et le règlement complet de la page (original-policy).

Rapports uniquement

Si vous débutez avec le CSP, il est logique d'évaluer l'état actuel de votre application avant de déployer une règle draconienne auprès de vos utilisateurs. Pour préparer un déploiement complet, vous pouvez demander au navigateur de surveiller une règle, de signaler les cas de non-respect, mais de ne pas 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 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 en surveillant une autre. C'est un excellent moyen d'évaluer l'impact des modifications apportées au CSP de votre application: activez la création de rapports pour une nouvelle règle, surveillez les rapports de non-respect et corrigez les bugs qui apparaissent. Lorsque vous êtes satisfait de son impact, commencez à appliquer la nouvelle règle.

Utilisation réelle

CSP 1 est tout à fait 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. Le niveau 2 du CSP est disponible dans Chrome depuis la version 40. Des sites de grande envergure comme Twitter et Facebook ont déployé l'en-tête (l'étude de cas de Twitter vaut la peine d'être lue), et la norme est prête à être déployée sur vos propres sites.

La première étape de la création d'une règle pour votre application consiste à évaluer les ressources que vous chargez réellement. Une fois que vous pensez avoir compris comment les éléments sont organisés dans votre application, configurez une règle en fonction de ces exigences. Examinons quelques cas d'utilisation courants et déterminons comment nous pourrions au mieux les prendre en charge dans les limites de protection du CSP.

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

  • Le bouton +1 de Google inclut un script à partir de https://apis.google.com et intègre un <iframe> à partir de https://plusone.google.com. Vous avez besoin d'une règle incluant ces deux origines pour intégrer le bouton. La valeur 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 stratégie de niveau 1 utilisant frame-src, le niveau 2 vous obligeait à la remplacer par child-src. Cela n'est plus nécessaire au niveau 3 du CSP.

  • Le bouton "J'aime" de Facebook propose plusieurs options d'implémentation. Nous vous recommandons de vous en tenir à la version <iframe>, car elle est placée dans un bac à sable sécurisé par rapport au reste de votre site. Il nécessite une directive child-src https://facebook.com pour fonctionner correctement. Notez que, par défaut, le code <iframe> fourni par Facebook charge une URL relative, //facebook.com. Remplacez-le par HTTPS : https://facebook.com. Il n'y a aucune raison d'utiliser HTTP si vous n'avez pas besoin de le faire.

  • Le bouton Tweet de Twitter repose sur 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.) script-src https://platform.twitter.com; child-src https://platform.twitter.com est prêt à l'emploi, à condition de déplacer l'extrait JavaScript fourni par Twitter vers 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 définir simplement un default-src sur 'none' et de surveiller votre console pour déterminer les ressources que vous devrez activer pour que les widgets fonctionnent.

L'inclusion de plusieurs widgets est simple: il vous suffit de combiner les directives de règles, en veillant à fusionner toutes les ressources d'un même type en une seule directive. Si vous souhaitez utiliser les trois widgets de réseaux sociaux, la règle se présente 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: confinement

Supposons que vous gérez un site bancaire et que vous souhaitiez vous assurer que seules les ressources que vous avez écrites peuvent être chargées. Dans ce scénario, commencez par une stratégie par défaut qui bloque absolument tout (default-src 'none'), puis développez-la.

Supposons que la banque charge toutes les images, le style et le script à partir d'un CDN sur https://cdn.mybank.net, et qu'elle se connecte via XHR à https://api.mybank.com/ pour récupérer divers éléments de données. Les cadres sont utilisés, mais uniquement pour les pages locales du site (pas d'origines tierces). Le site ne comporte pas de Flash, de polices ni d'extras. L'en-tête CSP le plus restrictif que nous pouvons 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

L'administrateur d'un forum de discussion sur les alliances de mariage souhaite s'assurer que toutes les ressources ne sont chargées que via des canaux sécurisés, mais il n'écrit pas vraiment beaucoup de code. Il ne peut pas réécrire de grandes parties du logiciel de forum tiers, qui est rempli à ras bord de script et de style intégrés. La règle suivante serait appliquée:

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 directives de script et de style n'héritent pas automatiquement de cette source. Chaque directive remplace complètement la valeur par défaut de ce type de ressource spécifique.

L'avenir

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

Si vous souhaitez participer à la discussion sur ces fonctionnalités à venir, consultez les archives de la liste de diffusion public-webappsec@ ou rejoignez-la.

Commentaires