Tous les articles

Comment générer un hash Subresource Integrity (SRI)

CentralCSP Team ·

Dernière mise à jour:

Subresource Integrity (SRI) est l'attribut integrity qui fait vérifier au navigateur les octets d'un fichier externe face à un hash que vous fournissez, et qui bloque le fichier s'il ne correspond pas. Pour l'utiliser, il vous faut deux choses : le hash, et le bon attribut sur la balise.

Générez le hash avec le générateur SRI : collez le fichier ou l'URL et il renvoie les valeurs SHA-256, SHA-384 et SHA-512 prêtes à coller. La valeur est le digest en base64 des octets bruts du fichier. Préfixez-la avec l'algorithme et posez-la sur la balise, associée à crossorigin pour un fichier cross-origin :

<script
  src="https://cdn.example.com/script.js"
  integrity="sha384-Li9vy3DqF8tnTXuiaAJuML3ky+er10rcgNR/VqsVpcw+ThHmYcwiB1pbOxEbzJr7"
  crossorigin="anonymous"></script>

Nouveau sur le mécanisme lui-même ? Subresource Integrity (SRI) expliqué couvre ce que c'est et ce contre quoi il protège. Le reste de cet article est le mode d'emploi et les pièges qui le cassent en silence.

Choisissez l'algorithme

Le SRI accepte sha256, sha384 et sha512. Préférez sha384 ou sha512. Le digest est calculé sur les octets bruts du fichier et encodé en base64, donc la seule chose qui change d'un algorithme à l'autre est la force et la longueur de la valeur.

Si vous listez plusieurs hashes dans la valeur integrity, le navigateur ne prend pas le premier. Il utilise l'algorithme le plus fort présent. Un sha256 à côté d'un sha384 signifie que seul le hash sha384 est vérifié, donc lister un plus faible à côté d'un plus fort n'affaiblit jamais le contrôle. Le générateur SRI renvoie les trois valeurs, vous pouvez donc coller celle que vous voulez.

Associez-le à crossorigin

Un <script> ou <link> cross-origin qui porte integrity mais pas crossorigin="anonymous" échoue toujours à se charger. C'est l'erreur SRI la plus fréquente.

Sans crossorigin, le navigateur récupère le fichier en mode no-cors et obtient une réponse opaque qu'il ne peut pas lire, donc il ne peut pas vérifier les octets face à votre hash et refuse d'exécuter le fichier. Ajouter l'attribut bascule la récupération vers CORS pour que le navigateur puisse lire la réponse et la vérifier.

<link
  rel="stylesheet"
  href="https://cdn.example.com/styles.css"
  integrity="sha384-Li9vy3DqF8tnTXuiaAJuML3ky+er10rcgNR/VqsVpcw+ThHmYcwiB1pbOxEbzJr7"
  crossorigin="anonymous">

Les fichiers same-origin sont déjà dans un état lisible, ils sont donc vérifiés sans crossorigin. L'attribut est l'exigence du cross-origin.

Vérifiez que ça marche

Chargez la page et guettez le fichier. Un hash correct se charge silencieusement. Un hash faux, ou un crossorigin manquant sur un fichier cross-origin, fait échouer le chargement et journalise une erreur d'intégrité dans la console du navigateur.

Pour confirmer qu'une non-correspondance est bien attrapée, changez un caractère dans la valeur integrity et rechargez : le script devrait être bloqué et la console devrait signaler que la ressource a échoué à son contrôle d'intégrité. Restaurez la valeur correcte une fois le blocage constaté.

Gardez les hashes à jour quand les fichiers changent

Le SRI ne se met pas à jour automatiquement. Le hash est lié aux octets exacts du fichier, il doit donc être régénéré chaque fois que le contenu du fichier change. C'est la fonctionnalité qui marche comme prévu, un fichier modifié avec un ancien hash est traité comme une falsification et bloqué.

C'est pourquoi une URL de CDN « latest » ou auto-minifiante casse le SRI : les octets peuvent changer sous vos pieds sans prévenir, et le prochain déploiement de leur côté bloque votre page. Épinglez une URL immuable et versionnée (un chemin de version spécifique, pas une étiquette mouvante) pour que le fichier que vous avez hashé soit celui que vous continuez de recevoir.

La charge de maintenance est aussi la raison pour laquelle les équipes suivent en premier lieu les scripts tiers qu'elles déploient. CentralCSP construit un inventaire de scripts de chaque script qui tourne sur vos pages à partir des rapports de hash CSP, pour que, quand un fichier tiers change, vous le voyiez au lieu de l'apprendre par un chargement bloqué.

Faites-le avec les outils de build

Générer des hashes à la main ne passe pas l'échelle au-delà de quelques fichiers. La plupart des bundlers peuvent émettre les attributs integrity automatiquement dans le cadre du build, vous pouvez donc l'automatiser avec Webpack ou Vite :

Ceux-ci gardent le hash synchronisé avec le fichier automatiquement, ce qui supprime le piège du régénérer-à-chaque-changement pour vos propres assets bundlés.

Ce n'est pas la même chose qu'un hash CSP

Un hash SRI et un hash CSP se ressemblent et sont faciles à confondre. Ils hashent des choses différentes.

  • Le SRI hashe un fichier externe et va dans l'attribut integrity sur la balise.
  • Une source CSP 'sha256-...' hashe le contenu d'un script inline et va dans la directive script-src de votre politique de sécurité du contenu.

Si vous autorisez un bloc <script> inline, vous voulez le hash CSP, pas le SRI. Comment générer un hash CSP (sha256) couvre ce cas.

Où l'exiger

Vous ajoutez integrity balise par balise. Pour exiger le SRI sur tout un document plutôt que balise par balise, il y a le header Integrity-Policy, qui indique au navigateur de refuser toute sous-ressource dans le périmètre qui se charge sans métadonnées d'intégrité.

Integrity-Policy: blocked-destinations=(script)

Integrity-Policy est récemment devenu disponible dans les versions actuelles de Chrome, Firefox et Safari. Voyez la référence Integrity-Policy pour les directives et le rapport qu'elle émet.

Prochaines étapes

Ajoutez integrity et crossorigin à vos scripts et feuilles de style cross-origin, épinglez leurs URL, et câblez votre bundler pour émettre les hashes de vos propres assets. Si un scanner vous a déjà amené ici, voyez si un scanner a signalé votre SRI. Pour voir quel code tiers vous chargez réellement avant de commencer à le hasher, commencez gratuitement et laissez CentralCSP inventorier vos scripts côté client.

Sources

Articles liés