CSP

Content Security Policy

Codeurs en Seine 2016

Nicolas Hoffmann / @Nico3333fr

CSP ?

Content Security Policy
=
« Politique de Sécurité des Contenus »

Un constat

Devrais-je le faire ?

Donner des directives au navigateur

  • Failles XSS (Cross-Site-Scripting)
  • Contenus « indésirables »
  • Mais aussi un outil d’amélioration continue…

Candidate Recommendations \o/

CSP 2 : Candidate Recommendation

Support de CSP 1

Support de CSP Level 1
http://caniuse.com/#feat=contentsecuritypolicy

Support de CSP 2

Support de CSP Level 2
http://caniuse.com/#feat=contentsecuritypolicy2

Fonctionnement

  • Entête HTTP
  • Directives pour chaque élément
<?php
header("Content-Security-Policy: <vos directives>");
?>
						

default-src

Si aucune directive de définie pour un type de contenu
=> utilise cette valeur


 default-src 'self' ;
 # self = même port, nom de domaine, protocole => OK
 

script-src (JavaScript)

Autoriser un nom de domaine


 script-src 'self' www.google-analytics.com ;
 # fichiers JS sur ce domaine => OK
 

img-src (images)

Autoriser des contenus embarqués


 img-src 'self' data: ;
 # img en Data-Uri  => OK
 

Autres directives


 style-src => styles CSS
 connect-src => AJAX, WebSocket, EventSource
 font-src => webfonts
 object-src => plugins (<object>, <embed>, <applet>)
 media-src => <audio>, <video>
 etc.
 frame-src, form-action, frame-ancestors, manifest-src…
strict-dynamic…

CSP, en pratique !

Un exemple

https://rocssti.net/exemple-csp-codeurs-seine

CSP, en pratique !

Une page sans CSP

Directives CSP

<?php
header("content-security-policy: default-src 'none';  
  script-src 'self' www.google-analytics.com ; 
  style-src 'self' ; 
  img-src 'self' www.google-analytics.com data: ;  
  font-src 'self'; 
  frame-ancestors 'none' ;  ");

// Pas autorisé JS/CSS inline 
// (<script>, onclick, <style> etc.) => ✖
?>

Règle de CSP

Tout ce qui n’est pas expressément autorisé dans les directives CSP… sera interdit.

Interdit = Bloqué, non affiché, non exécuté.

Et ça ne fait pas dans la demi-mesure…

Résultat ?

Élément Autorisé ?
styles_mini.css, jquery-mini.js
analytics.js (google-analytics.com)
evil.js (nicolas-hoffmann.net)
styles/JS inline
NIET

Notifications

Notifications dans la console (exemple sous Firefox)

Résultat

Une page avec CSP

Et comment on utilise CSP dans la vraie vie ?

Plusieurs façons de faire…

Mauvaise méthode

Faut pas y craindre = bourrin => IDIOT

Gamelle assurée

Plein d’outils

  • Report-URI
  • Report Only

Report-URI


 report-uri /csp-parser.php ;
 # envoie les erreurs sur cette adresse
 

Parser

<?php
$data = file_get_contents('php://input');

if ($data = json_decode($data, true)) {
 $data = json_encode(
  $data,
  JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES
  );
 mail(EMAIL, SUBJECT, $data);
}
?>
Voir CSP Report URI, exemples

Attention en prod

Très verbeux, pensez à filtrer/utiliser report-uri.io

Report-Only

<?php
header("Content-Security-Policy-Report-Only: <vos directives>");
?>

Faire « comme si » pour tester des directives

Hashes (CSP Level 2)

<script>alert('Hello, world.');</script>
script-src … 
  'sha256-qznLcsROx4GACP2dm0UCKCzCG-HiZ1guq6ZZDob_Tng=' ; 
<?php
echo base64_encode(hash('sha256', "alert('Hello, world.');", true));
?>

Nonces (CSP Level 2)

Nonce: Number used once

script-src … 
  'nonce-12345666789' ; 
<script nonce="12345666789">alert('coucou.');</script>

Doit être non trivial, non devinable, unique, regénéré à chaque fois :)

Pourquoi utiliser CSP ?

  • Pour vos utilisateurs
  • Pour VOUS (dév., gestionnaire de sites, etc.)

CSP pour vos utilisateurs/clients

CSP pour vous

  • Maîtrise globale du front
  • Recensement des sources de contenus et
    des sources d’emm*****
  • Éradique des mauvaises pratiques
  • Compagnon idéal de l’orthogonalité
  • Bonne pratique Opquast !

Conclusion :

CSP est votre futur meilleur ami !

Ressources

Merci beaucoup !

Pour votre attention.

Pour discuter :
Nicolas Hoffmann / @Nico3333fr