BreizhCamp - 9Úme édition
BreizhCamp - 9Úme édition - Laurent Brunet - 21 mars 2019
CSP Content Security Policy
C'est une couche de sécurité supplémentaire qui permet de détecter et d'atténuer certains types d'attaques, notamment les attaques XSS (Cross Site Scripting) et les attaques par injection de données.
Ces attaques peuvent ĂȘtre utilisĂ©es dans divers buts, comme le vol de donnĂ©es, le dĂ©facement de site ou la diffusion de malware.
Aujourd'hui, CSP est lâune des contre-mesures les plus prometteuses contre XSS.
https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
GrĂące Ă une en-tĂȘte HTTP Content-Security-Policy
Nous avons plusieurs maniĂšres de le faire :
â ïž Pour le mode Meta, on ne peut pas utiliser la directive frame-ancestors, report-uri, ou sandbox.
Content-Security-Policy: <policy-directive> ; <policy-directive>header("Content-Security-Policy: default-src 'self' https://domain.com https://*.domain.com; script-src 'self'âŠ", true);
add_header "Content-Security-Policy" "default-src 'none'; form-action 'none'; frame-ancestors 'none';"
Header set Content-Security-Policy "default-src 'none'; form-action 'none'; frame-ancestors 'none';"
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src 'self'">
script-src Directive dĂ©diĂ©e aux JavaScriptstyle-src Directive dĂ©diĂ©e aux stylesimg-src Directive dĂ©diĂ©e aux imagesconnect-src Directive dĂ©diĂ©e Ă lâĂ©tablissement de connexions depuis un objet XMLHttpRequest ou une WebSocketfont-src Directive dĂ©diĂ©e aux policesobject-src Directive dĂ©diĂ©e aux plugins (Ă©lĂ©ments object, embed, ou applet)media-src Directive dĂ©diĂ©e aux Ă©lĂ©ments audio et videodefault-src RĂšgle pour les Ă©lĂ©ments non spĂ©cifiĂ©sâ ïž Entre la directive default-src et les autres directives *-src, il n'y a pas d'hĂ©ritage.
child-src Directive dĂ©diĂ©e aux sources valides pour les web workers et les Ă©lĂ©ments comme frame et iframeform-action Directive dĂ©diĂ©e aux sources autorisĂ©es Ă utiliser lâattribut action dâun formulaireframe-ancestors Directive dĂ©diĂ©e aux Ă©lĂ©ments frame, iframe , object , embed ou applet base-uri Directive dĂ©diĂ©e aux sources valides pour lâĂ©lĂ©ment base qui indique lâadresse Ă utiliser pour recomposer toutes les adresses relatives contenues dans la pageđ€ Utilisation des nonces ou des hashes sur les scripts ou styles.
Toutes les directives prennent en charge des valeurs similaires. Chaque valeur sera sĂ©parĂ©e par un espace, Ă l'exception de none qui devrait ĂȘtre la seule valeur dĂ©finie.
*noneselfdata:https:*.lbrunet.comunsafe-inlineunsafe-evalreport-samplenonce-XXXsha256-XXX / sha384-XXX / sha512-XXX
content-security-policy:
default-src 'none' ;
style-src 'self' https://example.com 'report-sample' ;
script-src 'self' 'report-sample'
base-uri 'self' ;
object-src 'none' ;
img-src 'self' www.google.com data: ;
nonces et hashes autorisent le dĂ©veloppeur Ă annoter explicitement chaque script approuvĂ© (en ligne et externe), tout en empĂȘchant l'exĂ©cution des scripts injectĂ©s par une tierce personne.
content-security-policy:
style-src 'self' 'https://example.com' 'report-sample';
script-src 'self' 'nonce-rfOHm1spSuNZWnfsKipedA=='
'sha256-qznLcsROx4GACP2dm0UCKCzCG+HiZ1guq6ZZDob/Tng='
'report-sample';
object-src 'none';
Nonce : Number used Once (« numéro utilisé une seule fois »). Encore une fois, cela se définit dans les directives :
script-src 'nonce-rfOHm1spSuNZWnfsKipedA==' ;
<script nonce="rfOHm1spSuNZWnfsKipedA==">âŠ</script>
Cela revient Ă dire au navigateur de ne rien bloquer pour ce qui correspond Ă ce nonce.
â ïž Un nonce doit ĂȘtre unique, re-gĂ©nĂ©rĂ© Ă chaque fois, et bien entendu secret !
(Variable d'environnement par exemple)
script-src 'sha256-qznLcsROx4GACP2dm0UCKCzCG+HiZ1guq6ZZDob/Tng=' ;
<script>alert('Hello, world.');</script>
Similaire à nonce sur la directive, mais rien n'est spécifié au niveau de la balise script.
Exemple en PHP : echo base64_encode(hash('sha256', "alert('Hello, world.');", true));
â ïž Le moindre espace change le hash !
Si le script est statique (le contenu ne change pas), vous pouvez ajouter un hachage SHA-256 du script à la directive CSP afin que le script soit ajouté à la liste blanche.
Cependant, si le script est sujet à modification, vous avez la possibilité d'ajouter un nonce codé en base64 (valeur aléatoire) à la fois à la directive CSP et à la balise de script.
Une directive CSP est conçue pour bloquer le contenu qui nâa pas Ă©tĂ© explicitement inscrit sur la liste blanche, par un nom dâhĂŽte, un nonce ou un hashage.
La directive report-uri va nous aider à enregistrer les rapports en violation selon notre liste blanche définie.
add_header Content-Security-Policy "default-src 'none'; style-src 'self'; script-src 'self'; report-uri /reporting https://website.report-uri.com/r/d/csp/enforce";
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src 'self'; script-src 'self'; ";
La mise en place de CSP peut se faire de maniĂšre progressive depuis CSP2 avec l'en-tĂȘte HTTP Content-Security-Policy-Report-Only
L'approche est exactement la mĂȘme que Content-Security-Policy avec l'avantage de ne pas bloquer les ressources cĂŽtĂ© navigateur đ€
Avec Report-Only et report-uri vous pouvez tester des directives sans danger, reçevoir par mail, stocker en base de données, faire des stats de chaque violation, c'est rapide à mettre en place.
â ïž Vous pouvez cumuler Content-Security-Policy et Content-Security-Policy-Report-Only avec leur propre report-uri đ đ đ
"csp-report":{
"document-uri":"https://lbrunet.com/",
"referrer":"",
"violated-directive":"style-src-attr",
"effective-directive":"style-src-attr",
"original-policy":"default-src 'none'; img-src 'self'; style-src 'sha256-NfNzdSi31sG2cZuYD32kQkSqP/Ypsm8oUJfRqJWiauU=' 'self' 'report-sample'; object-src 'none'; script-src 'self' 'sha256-SOSPqWdDqDk3oeJJaRHm+RnKO5mWB8WP4683xY5G0cA=' 'nonce-KTDCTrMVDOSoPFV5fDJJUtgFD1nC3Kk3' https://code.jquery.com 'report-sample'; form-action 'self'; frame-ancestors 'none'; base-uri 'self'; font-src 'self'; report-uri https://9241978986399846732a.report-uri.com/r/d/csp/enforce /csp-reports",
"disposition":"enforce", // reporting
"blocked-uri":"inline",
"line-number":70,
"source-file":"https://lbrunet.com/",
"status-code":200,
"script-sample":"color: #1db954"
}
manifest-src a Ă©tĂ© ajoutĂ©worker-src a Ă©tĂ© ajoutĂ©report-uri est dĂ©conseillĂ© au profit de report-to'self' correspond maintenant Ă https: et wss:, mĂȘme sur les pages dont le schĂ©ma est http.script-dynamic uniquement pour les directives script-src et default-src script/style ou une eval en ligne est bloquĂ©, bloque-uri renvoie maintenant inline ou eval.navigate-to les liens, window.location.href, balises Meta refresh, ... Des informations sur l'orientation de cette directive'unsafe-hashed-attributes' 'unsafe-hashes' Permet d'activer des gestionnaires JS en ligne spĂ©cifiques avec un hachage. Des informations sur l'orientation de cette directiveCSP est mort, vive le CSP !
Sur l'insécurité des listes blanches et l'avenir de la politique de sécurité du contenu.
En 2016, Google publie un article sur les statistiques et les conseils pour
améliorer les statégies CSP avec la mise en place de script-dynamic
Parmi les stratégies de protection XSS :
unsafe-inline sans spécifier de nonce ou de hash, ce qui désactive essentiellement les capacités de protection CSP
default-src ni la directive object-src ainsi, les attaquants peuvent exploiter une vulnérabilité XSS en injectant un objet Flash malveillant capable d'exécuter JavaScript.
script-src 'self' https://example.org;
object-src 'none';
<script src="//example.org/script.js"></script>
L'attaquant pourrait abuser du point de terminaison JSONP en injectant un script avec l'URL suivante : <script src=âhttps://example.org/jsonp?callback=alert (1); //â></ script>
<script
nonce="rfOHm1spSuNZWnfsKipedA=="
src="//example.org/script.js">
</script>
Pour mettre en place une stratégie CSP strict, il faudra:
nonce Ă tous les <script>noncesha256 sha385 sha512onClick
Content-Security-Policy
script-src 'self' *.pinterest.com *.pinimg.com *.google.com connect.facebook.net
*.google-analytics.com *.accountkit.com *.facebook.com *.googletagmanager.com *.bnc.lt
*.branch.io *.yozio.com cdn.ampproject.org *.cdn.ampproject.org radar.cedexis.com
static.zdassets.com ekr.zdassets.com *.zopim.com *.zopim.org *.zopim.io
Content-Security-Policy
script-src 'sha256-Shc9zyGHe0eDIj8DYmcqZpX2gGW1wFcjo+6iwlq/WaQ='
'strict-dynamic' 'unsafe-inline' https:
'nonce-rfOHm1spSuNZWnfsKipedA==';
La valeur strict-dynamic permet l'exécution de scripts ajoutés dynamiquement à la page, à condition qu'ils aient été chargés par un script sûr et déjà sécurisé
script-src 'nonce-r4nd0m' 'strict-dynamic' 'unsafe-inline' https:;
object-src 'none'; base-uri 'none';
script-src 'nonce-r4nd0m' 'strict-dynamic' 'unsafe-inline' https:;
object-src 'none'; base-uri 'none';
script-src 'nonce-r4nd0m' 'strict-dynamic' 'unsafe-inline' https:;
object-src 'none'; base-uri 'none';
script-src 'nonce-r4nd0m' 'strict-dynamic' 'unsafe-inline' https:;
object-src 'none'; base-uri 'none';
default-src 'none'; object-src 'none'; base-uri 'self'; minimumreport-uriContent-Security-Policy-Report-Only