Explication du Content Security Policy

mieux protéger une application internet

Ce site ne sera plus alimenté de contenu après août 2014. Tous les nouveaux articles seront redigés pour www.waitingforcode.com
Dans l'article précédent consacré à la sécurité des applications web, on a abordé la problématique du Same Origin Policy. On peut donc passer à une nouvelle thématique qui sera Content Security Policy (CSP).

Au tout début on verra quelle est la définition du Content Security Policy. Ensuite on illustrera son utilisation dans le code.

Qu'est-ce que c'est Content Security Policy ?
CSP est une technique qui vise à atténuer les effets des attaques XSS. A l'origine développée par la fondation Mozilla, elle a été implémentée pour la première fois dans Firefox 4. La technologie permet de définir quels éléments (JavaScript et HTML) peuvent être exécutés sur la page. On peut, par exemple, préciser que l'on peut charger les images uniquement à partir d'un domaine particulier. En ce qui concerne le JavaScript, on peut, par exemple, bloquer l'exécution du code compris entre eval().

Comment cela fonctionne ? CSP est un en-tête, envoyé dans la réponse du serveur, dont le but est de contrôler le type des méthodes JavaScript et des éléments HTML pouvant être exécutés sur la page. L'en-tête, en fonction du naviageur, prend un des trois noms :
- Content-Security-Policy : utlisé par Chrome depuis sa version 25.
- X-Content-Security-Policy : utilisé par Firefox et Internet Explorer (accès très limité à cet en-tête pour la version 10 de ce dernier navigateur).
- X-WebKit-CSP : utilisé par Chrome, Safari et autres navigateurs basés en WebKit en 2011, à l'étape d'expérimentation.

L'en-tête est composé de cette manière : Content-Security-Policy : nom de l'attribut le nom de la valeur; nom de l'attribut le nom de la valeur.

Voici une liste des attributs que peut prendre cet en-tête :
- default-src : par défaut toutes les directives sont ouvertes. En indiquant cet attribut, on active la surcharge de cette configuration ouverte.
- base-uri : spécifie quels URIs peuvent être utilisés par l'élément <base>.
- script-src : détermine quels scripts peuvent être exécutés.
- object-src : détermine quels plugin peuvent être chargés.
- style-src : détermine quels styles peuvent être appliqués à la page.
- img-src : détermine d'où la page peut charger les images.
- media-src : détermine d'où la page peut charger les fichiers vidéo et audio.
- frame-src : détermine d'où la page peut charger les frames.
- font-src : détermine d'où la page peut charger les polices.
- connect-src : détermine les URIs qui peuvent être chargés via les scripts.
- form-action : détermine quel URL peut être utilisé pour l'attribut action de l'élément <form />
- sandbox : il a l'effet semblable à l'attribut sandbox de l'élément <iframe />. Une fois spécifiée, il bloque l'exécution des popups, scripts et plugins.
- plugin-types : peut limiter les plugins chargés à ceux dont le type MIME y est renseigné.
- reflected-xss : l'équivalent de l'en-tête non standard, X-XSS-Protection, il indique au naviageut d'activer ou de désactiver les filtres utilisés pour empêcher les attaques XSS.
- report-uri : détermine l'URI auquel le navigateur doit envoyer les rapports en cas d'une violation du CSP .

D'après le draft du groupe W3C travaillant sur CSP, certains attributs ci-dessus sont dans l'état expérimental. Il s'agit de : base-uri, form-action, plugin-type et reflected-xss.

Mettre en place CSP
Maintenant quand on sait comment fonctionne Content Security Policy, on peut s'occuper de le mettre en place. Dans notre exemple on utilisera un simple script PHP qui renverra CSP par la méthode Header(). La page ne permettra pas de charger les images de la page Nasa (http://solarsystem.nasa.gov/). Elle ne permettra pas non plus l'exécution de la méthode eval(). On créera aussi un autre fichier PHP qui traitera toutes les violations du CSP (attribut report-uri).

Voici donc la page qui sera appelée :

<?php
header("Content-Security-Policy : default-src 'self'; img-src localhost; report-uri http://localhost/csp/save_report.php");
?>
<script type="text/javascript">
var text = "test text";
alert(eval("text"));
</script>
<img src="http://solarsystem.nasa.gov/multimedia/gallery/711377main_grail20121205_4x3_full.jpg" alt="" />


En exécutant ce code on verra que ni l'image est chargée, ni le code eval exécuté. En plus, notre fichier save_report.php est appelé pour les deux événements de violation (image et script). Voici son code est un fragment de ce qu'il sauvegarde :

<?php
$violationLog = json_decode(file_get_contents("php://input"));
$reportsLog = $_SERVER["DOCUMENT_ROOT"]."/csp/reports.log";
$reports = file_get_contents($reportsLog);
$reports .= "
".date("Y-m-d H:i:s")." : [CSP] Violated : ".print_r($violationLog, true);


file_put_contents($reportsLog, $reports);

/**
* And sample output :
2013-05-30 19:05:58 : [CSP] Violated : stdClass Object
(
[csp-report] => stdClass Object
(
[document-uri] => http://localhost/csp/page.php
[referrer] =>
[violated-directive] => default-src 'self'
[original-policy] => default-src 'self'; img-src localhost; report-uri http://localhost/csp/save_report.php
[blocked-uri] =>
)

)

2013-05-30 19:05:58 : [CSP] Violated : stdClass Object
(
[csp-report] => stdClass Object
(
[document-uri] => http://localhost/csp/page.php
[referrer] =>
[violated-directive] => img-src localhost
[original-policy] => default-src 'self'; img-src localhost; report-uri http://localhost/csp/save_report.php
[blocked-uri] => http://solarsystem.nasa.gov
)

)
*/

On constate qu'en enlévant l'en-tête Content-Security-Policy, l'image apparaît correctement et l'expression dans eval() est traitée.

Content Security Policy est donc une nouvelle petite révolution du milieu web côté navigateur. Il permet de mieux contrôler les ressources utilisées par la page et complète donc à 100% toute sorte des filtres XSS qui, dans certains cas, peuvent être contournés et donc causer des trous de sécurité.
Bartosz KONIECZNY 21-04-2014 00:00 sécurité des applications web
Moi

Développeur d'applications Internet et journaliste passionné par l'adjectif français. Un aigle polonais orienté vers la progression, volant très haut et écoutant du zouk après les matches du foot français.

Vous appréciez mon travail ?

Pour contribuer au développement de ce site, ou pour remercier pour des articles rédigés, vous pouvez faire un don.

Un conseil Symfony1

Comment changer le contexte ?

Si vous travaillez sur un module du backend et avez besoin d'utiliser pendant un moment l'élément d'une autre application (par exemple, frontend), il suffit de changer le contexte par :

sfContext::switchTo('frontend');