CentralCSP
PolitiquesContent-Security-PolicyValeurs

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>
ValeurStatutDescription
Source de nonce 'nonce-<base64>'✅ BonUn jeton frais et impossible à deviner, propre à chaque réponse, correspondant à l'attribut nonce de l'élément.
Source de hash pour du contenu inline✅ BonUne empreinte sha256, sha384 ou sha512 du texte exact du script ou du style inline.
Source de hash pour des scripts externes✅ BonCorrespond à 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 nonce de 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, sha384 ou sha512. L'algorithme de la source doit correspondre à celui que vous avez calculé.
  • Pour correspondre à un event handler inline (comme onclick=) ou à un attribut style=, 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-endpoint
Reporting-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

Sources

On this page