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 WebSocket
font-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 video
default-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 iframe
form-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.
*
none
self
data:
https:
*.lbrunet.com
unsafe-inline
unsafe-eval
report-sample
nonce-XXX
sha256-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 directive
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>
nonce
sha256
sha385
sha512
onClick
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-uri
Content-Security-Policy-Report-Only