Comment generer un hash CSP (sha256) pour un script inline
CentralCSP Team ·
Dernière mise à jour:
Un hash CSP autorise un script inline précis par l'empreinte de son contenu. Une politique de sécurité du contenu (CSP) est un header de réponse HTTP qui indique au navigateur quels scripts il peut exécuter, et par défaut elle bloque les scripts inline. Une source de type hash vous permet de garder un bloc inline spécifique fonctionnel sans tous les réactiver.
En résumé : calculez un condensé SHA-256 du texte exact à l'intérieur de la balise <script>, encodez-le en base64, et ajoutez-le à script-src sous la forme 'sha256-...'. Le navigateur hashe chaque script inline qu'il trouve et n'exécute que ceux dont le hash figure dans votre liste. Si vous préférez éviter le calcul, collez le snippet dans notre générateur de hash et copiez la valeur de source qu'il retourne.
Vous débutez avec la gestion de l'inline ? Pourquoi ne jamais utiliser unsafe-inline en CSP explique pourquoi le hashing vaut mieux que 'unsafe-inline'.
Ce qu'est un hash CSP
Une source de type hash est un condensé cryptographique encodé en base64 du contenu d'un script inline, écrit dans votre politique. Quand le navigateur rencontre un <script> inline, il calcule le même condensé sur le contenu de ce script et le compare aux hash de la directive. S'il y a correspondance, le script s'exécute ; sinon, il est bloqué.
Comme le hash est lié aux octets exacts du script, un attaquant qui injecte un autre code inline ne peut pas le faire correspondre, donc le script injecté ne s'exécute jamais. C'est ce qui fait d'un hash une façon sûre d'autoriser des blocs inline précis.
Les trois formes de source
La CSP prend en charge trois algorithmes de condensé, écrits avec l'algorithme en préfixe :
'sha256-...''sha384-...''sha512-...'
Les trois sont largement pris en charge par les navigateurs actuels. SHA-256 est le choix courant ; les variantes plus longues produisent des valeurs plus longues sans bénéfice de sécurité pour des scripts de taille habituelle. La valeur après le préfixe est l'encodage base64 du condensé brut, pas sa forme hexadécimale.
Le hash porte sur le contenu exact (les espaces comptent)
Le condensé est calculé sur le texte exact entre la balise ouvrante et la balise fermante, pas sur les balises elles-mêmes ni sur les attributs. Chaque caractère compte : espaces, tabulations, retours à la ligne en fin, et casse font tous partie du contenu.
<script>console.log("hello");</script>Le hash de ce bloc couvre exactement console.log("hello");. Ajoutez un espace en début, un retour à la ligne en fin, ou changez de style de guillemets et le condensé change, donc la source que vous avez listée ne correspond plus et le navigateur bloque le script. Calculez le hash à partir des octets finaux, minifiés, que vous servez réellement, et non d'une copie embellie.
Calculer le hash
Pour un seul snippet, collez le code inline dans le générateur de hash et il retourne la source 'sha256-...' prête à déposer dans la politique, sans ligne de commande et sans erreur d'espaces.
Dans une étape de build, calculez-le en Node.js avec le module intégré crypto :
const crypto = require("crypto");
function cspHash(content) {
const digest = crypto.createHash("sha256").update(content, "utf8").digest("base64");
return `'sha256-${digest}'`;
}
console.log(cspHash('console.log("hello");'));Cela produit la même valeur, calculée à partir des octets UTF-8 exacts du contenu du script, câblez-le donc dans votre build pour garder les hash synchronisés à mesure que le code inline change.
Où le hash se place
Ajoutez la source à la directive qui régit la ressource. Pour les scripts inline, c'est script-src ; pour les styles inline, c'est style-src. Vous pouvez lister plusieurs hash pour autoriser plusieurs blocs inline.
Content-Security-Policy: script-src 'self' 'sha256-q1V8...=' 'sha256-Hk9p...='Vous pouvez mélanger des hash avec 'self' et des sources d'hôtes pour vos fichiers externes, et les hash ne s'appliquent jamais qu'au contenu inline. Si la directive contient aussi un nonce ou un hash, le navigateur ignore 'unsafe-inline' dans cette même directive, donc un 'unsafe-inline' oublié ne défait pas vos hash (retirez-le quand même).
Hash vs nonce, lequel choisir
Les hash et les nonces résolvent le même problème, autoriser des scripts inline précis, mais conviennent à des contenus différents.
- Utilisez un hash pour du code inline statique qui ne change pas d'une réponse à l'autre : un bundle inline produit au build, un snippet d'analytics figé, un petit bloc constant. Vous calculez le hash une fois au moment du build et il reste valide jusqu'à ce que le contenu change.
- Utilisez un nonce pour les pages dynamiques rendues côté serveur où le contenu inline ou l'ensemble des scripts inline varie d'une requête à l'autre. Un nonce est une valeur aléatoire fraîche par réponse et ne dépend pas du contenu du script.
Un hash ne demande aucun travail par requête, ce qui le rend idéal pour l'hébergement statique et les pages mises en cache. Un nonce demande au serveur de générer et d'injecter une valeur à chaque réponse. De nombreux sites utilisent des hash pour les snippets figés et un nonce pour les blocs rendus côté serveur.
Le cas particulier des handlers inline ('unsafe-hashes')
Une source de type hash simple autorise des blocs <script> inline. Elle ne couvre pas les attributs d'event handler inline comme onclick="..." ni les URL javascript:. Autoriser un handler par son hash nécessite le mot-clé distinct 'unsafe-hashes', qui assouplit la politique et qu'il vaut mieux éviter.
<!-- Hashing this needs 'unsafe-hashes', which weakens the policy -->
<button onclick="saveForm()">Save</button>La meilleure correction est de retirer le handler inline et de l'attacher depuis un script hashé ou nonçé avec addEventListener :
// markup: <button id="save">Save</button>
document.getElementById("save").addEventListener("click", saveForm);Cela garde la politique stricte et évite 'unsafe-hashes' entièrement.
Visualisez-le dans vos reports
Quand un hash ne correspond pas (souvent un changement d'espaces que vous avez manqué), le navigateur bloque le script et signale une violation. CentralCSP collecte ces reports issus du trafic réel et les regroupe, pour qu'un hash désynchronisé apparaisse comme un blocage récurrent plutôt qu'une rupture silencieuse. Vous pouvez démarrer un essai gratuit et y pointer un header Report-Only pendant que vous déployez vos hash.
Pour la référence complète des directives et des mots-clés, voyez la référence de la politique CSP.

Questions fréquentes
Pourquoi mon hash CSP ne correspond-il pas au script ?
Presque toujours une histoire d'espaces. Le hash couvre le texte exact entre les balises, y compris les espaces et retours à la ligne en début ou en fin. Calculez-le à partir des octets finaux servis, pas d'une copie formatée, ou utilisez le générateur de hash sur le snippet exact.
Dois-je utiliser un hash ou un nonce ?
Utilisez un hash pour les scripts inline statiques qui changent rarement, et un nonce pour les pages dynamiques rendues côté serveur. Les hash ne demandent aucun travail par requête ; les nonces ne dépendent pas du contenu du script.
Un hash CSP peut-il autoriser un handler onclick inline ?
Pas avec un hash simple. Autoriser un event handler inline par hash nécessite le mot-clé 'unsafe-hashes', qui assouplit la politique. Retirez le handler inline et attachez-le plutôt avec addEventListener.