Hashs et nonces
Comment les sources nonce et hash CSP autorisent des scripts et styles inline précis sans unsafe-inline, avec les règles de chacun.
Dernière mise à jour:
Les sources nonce et hash permettent à une politique de sécurité du contenu (CSP)
d'autoriser un script ou un style inline précis sans activer
'unsafe-inline'.
Un nonce est un jeton à usage unique partagé entre la politique et l'élément ; un
hash est une empreinte du contenu exact de l'élément. Tous deux disent « fais
confiance à ce code inline précis et à rien d'autre », ce qui est le fondement
d'une CSP stricte.
Une politique à nonce et la balise script qui lui correspond :
Content-Security-Policy: script-src 'nonce-{RANDOM}'<script nonce="{RANDOM}">init();</script>Syntaxe
Une source de nonce est 'nonce-' suivi d'une valeur base64. Une source de hash
est une étiquette d'algorithme, sha256, sha384 ou sha512, un tiret, puis
l'empreinte base64.
Content-Security-Policy: script-src 'nonce-r4nd0m' 'sha256-RFWPLDbv2BY+rCkDzsE+0fr8ylGr2R2faWMhq4lfEQc='L'élément correspondant référence le même nonce, ou a simplement un contenu dont l'empreinte est égale au hash.
<script nonce="r4nd0m">doSomething();</script>| Valeur | Statut | Description |
|---|---|---|
Source de nonce 'nonce-<base64>' | ✅ Bon | Un jeton frais et impossible à deviner, propre à chaque réponse, correspondant à l'attribut nonce de l'élément. |
| Source de hash pour du contenu inline | ✅ Bon | Une empreinte sha256, sha384 ou sha512 du texte exact du script ou du style inline. |
| Source de hash pour des scripts externes | ✅ Bon | Correspond à l'empreinte d'intégrité de type SRI du script. Largement pris en charge par les navigateurs actuels. |
Hash pour event handlers, avec 'unsafe-hashes' | ❌ Risqué | Étend la correspondance des hashs aux handlers inline et aux attributs style=, rouvrant cette surface. |
Lorsqu'un nonce ou un hash est présent dans une directive,
'unsafe-inline'
dans cette même directive est ignoré. Une fois un nonce ou un hash ajouté, retirez
'unsafe-inline' : le navigateur l'ignore déjà, donc il ne fait qu'encombrer la
politique.
Règles des nonces
Un nonce ne vous protège que si un attaquant ne peut ni le prédire ni le réutiliser. Suivez toutes ces règles.
- Générez-le côté serveur, à neuf pour chaque réponse. Un nonce statique figé dans
un template équivaut à
'unsafe-inline', car un script injecté peut recopier la valeur connue. - Utilisez un générateur aléatoire cryptographiquement sûr (CSPRNG) avec au moins 128 bits d'entropie, encodé en base64.
- Rendez-le unique par réponse. Ne mettez jamais en cache une page avec son nonce, et n'en réutilisez jamais un entre requêtes.
- Placez la même valeur dans la politique et dans l'attribut
noncede l'élément. Un décalage bloque le script.
Content-Security-Policy: script-src 'nonce-8IBTHwOdqNKAWeKl7plt8g=='<script nonce="8IBTHwOdqNKAWeKl7plt8g==">init();</script>Voir mettre en place un nonce CSP pour un guide par framework.
Règles des hashs
Une source de hash correspond à un élément inline dont le contenu se hache vers l'empreinte donnée. Elle ne demande aucun jeton par réponse, ce qui en fait un bon choix pour du code inline statique.
- L'empreinte est calculée sur le contenu texte exact du
<script>ou du<style>inline : les octets UTF-8 entre les balises, chaque espace, retour à la ligne et caractère compté, sans les balises elles-mêmes. Un seul changement d'espace invalide le hash. - Utilisez
sha256,sha384ousha512. L'algorithme de la source doit correspondre à celui que vous avez calculé. - Pour correspondre à un event handler inline (comme
onclick=) ou à un attributstyle=, il faut aussi'unsafe-hashes'dans la directive. Sans lui, les hashs ne correspondent qu'aux blocs<script>et<style>complets. - Hacher un script externe contre son empreinte d'intégrité de type SRI est défini dans CSP3 et fonctionne dans les navigateurs actuels. Un hash CSP n'est pas la même chose qu'un hash Subresource Integrity ; voir SRI vs hash CSP pour la distinction.
Calculer un hash
Le hash est l'empreinte base64 du contenu inline exact, sans les balises et sans
retour à la ligne final, écrite dans la politique sous la forme
'sha256-<sortie>'. Collez le snippet dans le
générateur de hash et il renvoie la source prête à
l'emploi. Voir
calculer un hash sha256 CSP pour des exemples
détaillés.
Valeurs non sûres à éviter
L'échec qui annule un nonce est la réutilisation : un nonce prévisible, statique
ou mis en cache permet à un script injecté de présenter la valeur connue et de
s'exécuter. Pour les hashs, le piège est un 'unsafe-hashes' appliqué trop
largement, puisqu'il étend la correspondance aux attributs ; cantonnez-le aux
hashs exacts dont vous avez besoin. Ne retombez jamais sur 'unsafe-inline' pour
« faire marcher le nonce » : il est ignoré quand un nonce est présent et ne fait
que brouiller la politique.
Contre quoi cela protège
Les nonces et les hashs sont la façon dont une politique distingue la poignée de
scripts inline que vous avez écrits de n'importe quel script inline injecté par un
attaquant, ce qui bloque le vecteur XSS central que 'unsafe-inline' laisse
ouvert. Auditez si une politique s'appuie réellement dessus avec
l'évaluateur CSP.
Contournements et limites connus
Un nonce divulgué ou devinable est le contournement pratique, donc l'entropie et l'unicité par réponse ne sont pas optionnelles. Les hashs sont fragiles face aux changements de contenu : une étape de build qui reformate ou minifie le code inline invalide le hash stocké et casse le script jusqu'à ce que vous le recalculiez.
Risques
Le risque opérationnel courant est un déploiement qui met en cache une page avec son nonce, figeant un même nonce pour de nombreux utilisateurs, ce qui casse à la fois des scripts légitimes (quand le cache et le header divergent) et affaiblit la protection. L'équivalent côté hash est de livrer un changement de code sans mettre à jour le hash. Déployez les changements en mode Report-Only pour attraper les deux avant qu'ils n'atteignent les utilisateurs.
Recommandation
Utilisez un nonce quand la page est rendue à chaque requête et que vous pouvez
injecter une valeur fraîche à la fois dans le header et dans le balisage ; il gère
proprement le code inline dynamique. Utilisez un hash quand le contenu inline est
statique et que vous préférez ne pas faire circuler un nonce à travers des couches
de cache, ou quand vous ne pouvez pas définir de header au moment de la requête
(un hash fonctionne dans une politique <meta>). Dans les deux cas, associez-le à
'strict-dynamic'
pour que le script d'amorçage de confiance puisse charger le reste. Définissez
explicitement les directives restantes pour que rien ne se rabatte implicitement :
Content-Security-Policy:
default-src 'self';
script-src 'nonce-{RANDOM}' 'strict-dynamic';
style-src 'self';
img-src 'self';
font-src 'self';
connect-src 'self';
media-src 'self';
manifest-src 'self';
frame-src 'none';
worker-src 'self';
object-src 'none';
base-uri 'none';
form-action 'self';
frame-ancestors 'none';
upgrade-insecure-requests;
report-to csp-endpointReporting-Endpoints: csp-endpoint="https://<Endpoint-ID>.report.centralcsp.com"C'est la CSP stricte que la
cheat sheet CSP de l'OWASP
et le guide de CSP stricte de web.dev
recommandent plutôt que les allowlists d'hôtes : seuls les scripts que vous avez
marqués s'exécutent, et aucun 'unsafe-inline' n'affaiblit la politique.
Exemples
Une politique de script stricte utilisant un nonce et 'strict-dynamic' :
Content-Security-Policy:
script-src 'nonce-8IBTHwOdqNKAWeKl7plt8g==' 'strict-dynamic';
object-src 'none';
base-uri 'none'Autoriser un script inline statique par hash :
Content-Security-Policy: script-src 'self' 'sha256-RFWPLDbv2BY+rCkDzsE+0fr8ylGr2R2faWMhq4lfEQc='Prise en charge par les navigateurs
Les sources de nonce et les sources de hash sha256/sha384/sha512 font partie
du cœur de CSP et sont largement prises en charge par les navigateurs actuels.
L'extension 'unsafe-hashes' pour les attributs est également largement prise en
charge. La correspondance de hash pour les scripts externes est désormais
largement prise en charge par les navigateurs actuels elle aussi.
FAQ
Faut-il utiliser un nonce ou un hash ?
Utilisez un nonce quand la page est rendue à chaque requête et que vous pouvez
injecter une valeur fraîche à la fois dans le header et dans le balisage ; il gère
proprement le code inline dynamique. Utilisez un hash quand le contenu inline est
statique ou que vous ne pouvez pas définir de header au moment de la requête,
puisqu'un hash fonctionne dans une politique <meta>.
Comment générer un hash CSP ?
Calculez l'empreinte base64 du contenu inline exact, sans les balises et sans
retour à la ligne final, puis écrivez-la dans la politique sous la forme
'sha256-<sortie>'. Un seul changement d'espace invalide le hash. Collez le
snippet dans le générateur de hash et il renvoie la
source prête à l'emploi.
Voir aussi
- Mots-clés
- Source hôte
- Directive script-src
- Directive style-src
- Mettre en place un nonce CSP
- Calculer un hash sha256 CSP
- Outil générateur de hash
Sources
Source de schéma
Comment fonctionnent les sources de schéma CSP comme https, data et blob, et pourquoi data et blob sont dangereux dans script-src mais sûrs dans img-src.
Mot-clé report-sha256
Les mots-clés de hash report-only report-sha256, report-sha384 et report-sha512 qui alimentent le reporting de hash de script du navigateur et le SBOM.