CSP

C’est Super Palpitant

Ateliers Paris Web 2017

Nicolas Hoffmann / @Nico3333fr

Slides à disposition ici

(page lourde avec pleins de GIF, oui je sais c’ai mal…) https://nicolas-hoffmann.net/CSP-PW2017

Atelier = tu participes !

CSP ?

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

Donner des directives au navigateur

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

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.allyouneedislove.org ;
 # fichiers JS sur ce domaine => OK
 

img-src (images)

Autoriser des contenus embarqués


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

CSP niveau 1

  • script-src : les sources autorisées pour les scripts JS
  • style-src : styles CSS
  • img-src : images
  • connect-src : pour XMLHttpRequest (AJAX), WebSocket ou EventSource
  • font-src : web fonts
  • object-src : plug-ins (par exemple : <object>, <embed>, <applet>)
  • media-src : pour les balises <audio> et <video>

CSP niveau 2

  • child-src : pour les web workers et <frame> et <iframe> (remplace frame-src de CSP 1)
  • form-action : pour l’attribut action d’un formulaire
  • base-uri : pour l’élément <base>
  • frame-ancestors : les sources autorisées à embarquer la ressource dans <frame> <iframe>, <object>, <embed> ou <applet>
  • upgrade-insecure-requests : réécrire l’URL en changeant HTTP en HTTPS
  • Etc.

CSP, en pratique !

Un exemple

https://rocssti.net/exemple-csp-paris-web2017

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

D’autres 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

Exemple


 {
    "csp-report": {
        "blocked-uri": "",
        "document-uri": "https://van11y.net/",
        "original-policy": "default-src 'none'; script-src https://van11y.net; style-src https://van11y.net; img-src https://van11y.net; font-src https://van11y.net; connect-src https://van11y.net; child-src https://van11y.net; frame-ancestors 'none'; manifest-src https://van11y.net; report-uri https://van11y.net/csp-parser.php",
        "referrer": "https://material.io/resizer/",
        "violated-directive": "frame-ancestors 'none'"
    }
}

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-123424242' ; 
  
  // $nonce_script = hash('sha512', random_bytes(42));
<script nonce="123424242">alert('coucou.');</script>

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

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

Bravo !


Vous savez tout… ou presque.

Passons à quelques considérations pratiques

Gniark

« Niveaux » d’implémentation CSP

On va jouer !

CSP Level 1
CSP Level 5

Niveau 1

CSP Level 1

Niveau 1

Content-Security-Policy: 
default-src * data: ; 
script-src * 'unsafe-inline' 'unsafe-eval' ; 
style-src * 'unsafe-inline' data: ; 
frame-ancestors 'none' ;
Équivalent de X-Frame-Options
Devrait être votre minimum vital

Niveau 2

CSP Level 2

Niveau 2

Content-Security-Policy: 
default-src 'self' data: ; 
script-src 'self' www.foo.com 'unsafe-inline' 'unsafe-eval' ; 
style-src 'self' www.coincoin.com 'unsafe-inline' data: ; 
frame-ancestors 'none' ;
Indiquez vos sources, plus de sélecteur wildcard (*)

Niveau 3

CSP Level 3

Niveau 3

Content-Security-Policy: 
default-src 'self' data: ; 
script-src 'self' www.foo.com 'unsafe-inline' 'unsafe-eval' ; 
style-src 'self' www.coincoin.com data: ; 
frame-ancestors 'none' ;
Plus d’unsafe-inline pour les styles,
surtout pas de data: pour le JS

Niveau 4

CSP Level 4

Niveau 4

Content-Security-Policy: 
default-src 'self' ; 
script-src 'self' www.foo.com  ; 
style-src 'self' www.coincoin.com data: ; 
frame-ancestors 'none' ;
Plus d’'unsafe-inline' 'unsafe-eval' pour le JS

Niveau 5

CSP Level 5

Niveau 5

Content-Security-Policy: 
default-src 'none' ; 
script-src 'self' www.foo.com  ; 
style-src 'self' www.coincoin.com data: ; 
frame-ancestors 'none' ;
report-uri /csp-parser.php
default-src 'none' => directives toutes définies

Niveau 5+

  • CSP niveau 2 permet de restreindre à des chemins
  • Les contrôles d’intégrités sont plus durs que les origines
  • Possible de définir des directives CSP pour d’autres fichiers
  • Et CSP 3 amène du plus lourd encore…
  • … MAIS MAIS MAIS…

Pragmatisme

Sécurité, front-end, temps.

Une triade impossible à éviter

  • Si vous en êtes au niveau 5 et que ça suffit pas…
  • Contexte de votre projet.

Des petites choses à préparer

  • Sources de contenus ?
  • Maîtrise du front
  • Services utilisés ?
  • Etc.

Résultante

Différentes approches.

À Vous !

Petit outil certifié ISO-1664

https://csp.nicolas-hoffmann.net/playground.php
Login: Paris
Pass: Ouaib

Des exemples d’exercices (1/3)

  • Faites joujou avec l’outil précédent
  • Trouvez des directives pour des services (Collection of examples)
  • Trouvez les directives pour vos sites

Des exemples d’exercices (2/3)

Imaginez d’autres usages pour CSP
  • Migration HTTPS
  • Nettoyage de pages cracras
  • À vous ?

Des exemples d’exercices (3/3)

  • Concevoir un site recensant les directives pour des sites ?
  • Open-bar, je suis à disposition :)

Un petit mot du futur de CSP ?

Pour finir, en conclusion

CSP c’est bien 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é
  • Chainon manquant entre sécurité et front-end
  • Réduit la voilure sur le front

Bref :

CSP rocks !

Ressources

Merci beaucoup !

Pour votre attention.

Pour discuter :
Nicolas Hoffmann / @Nico3333fr