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. L'aide-mémoire XSS est un exemple ancien mais représentatif des méthodes qu'un pirate informatique pourrait utiliser pour violer 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 méchants. 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 par lui-même que le code provenant de apis.google.com
est génial, contrairement à celui provenant de apis.evil.example.com
. Le navigateur télécharge et exécute 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 instruction qui contrôle un ensemble de droits liés au script 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 systématiquement JavaScript à partir de apis.google.com
via HTTPS, ainsi qu'à partir de l'origine de la page actuelle.
Lorsque cette règle est 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 sur votre site, il se heurte à un message d'erreur plutôt qu'au succès espéré.
La stratégie s'applique à un large éventail de ressources
Bien que les ressources de script constituent les risques de sécurité les plus évidents, CSP fournit un ensemble complet d'instructions de stratégie qui permettent de contrôler de manière assez précise les 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
répertorie les URL des nœuds de calcul et du contenu des frames 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 les polices Web. Les polices Web de Google peuvent être activées viafont-src https://themes.googleusercontent.com
.form-action
répertorie les points de terminaison valides pour l'envoi à partir de balises<form>
.frame-ancestors
spécifie les sources pouvant intégrer la page active. 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
est obsolète depuis le niveau 2, mais il est restauré 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 descript-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 worker, worker partagé ou service worker. 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, par exemple 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 instruction 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 instruction serait simplement ignorée. Un code comme celui-ci spécifierait correctement les deux origines comme valides :
script-src https://host1.com https://host2.com
Si, par exemple, 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 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 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é, du 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 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 y attendre,
'none'
ne correspond à rien. 'self'
correspond à l'origine actuelle, mais pas à ses sous-domaines.'unsafe-inline'
autorise le code JavaScript et CSS intégré. (Nous y reviendrons plus en détail plus tard.)'unsafe-eval'
permet d'utiliser des mécanismes de conversion texte-JavaScript tels queeval
. (Nous y reviendrons également.)
Ces mots clés doivent être placés entre guillemets simples. Par exemple, script-src 'self'
(avec des 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.
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. Cet article 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. 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 aussi 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 le code suivant à partir de :
<script>
function doAmazingThings() {
alert('YOU AM AMAZING!');
}
</script>
<button onclick="doAmazingThings();">Am I amazing?</button>
par 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 CSP. C'est déjà une bonne pratique, quelle que soit votre utilisation de CSP. Le code JavaScript intégré mélange la structure et le 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 se protéger contre une variété de méthodes d'exfiltration de données étrangement intelligentes que le CSS permet.
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 instruction script-src
ou style-src
. Vous pouvez également utiliser un nonce ou un hachage (voir ci-dessous), mais ce n'est absolument pas autorisé.
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 fastidieux, cela peut être utile au pincement.
Pour utiliser un nonce, attribuez un attribut nonce à votre tag 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
, en plus du 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>
. Les majuscules et les espaces sont également importants, y compris les espaces de début ou de fin.
Une recherche Google sur la génération de hachages SHA vous permettra de trouver des solutions dans un grand nombre de langues. À partir de la version 40 de Chrome, 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.
Évaluation également
Même lorsqu'un pirate informatique ne peut pas injecter directement un script, il peut inciter votre application à convertir un texte inerte en code JavaScript exécutable et l'exécuter 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 de 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 les données JSON via l'
JSON.parse
intégré plutôt que d'utilisereval
. 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
ousetInterval
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 deeval
. 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 de texte en 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. L'interdiction de l'exécution de chaînes rend beaucoup plus difficile pour un pirate informatique l'exécution de 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 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
).
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 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 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 dehttps://plusone.google.com
. Vous avez besoin d'une règle qui inclut ces deux origines pour pouvoir intégrer le bouton. La valeur minimale estscript-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 utilisantframe-src
, le niveau 2 vous obligeait à la remplacer parchild-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 directivechild-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 contient ni Flash, ni polices, ni éléments supplémentaires. 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.