# Hashes SRI automatiques avec webpack et Vite (/fr/blog/sri-webpack-vite)



Un bundler émet des dizaines de fichiers de chunks hashés, dont les noms et le contenu changent à chaque build. Calculer un hash Subresource Integrity (SRI) pour chacun à la main n'est pas réaliste. La solution est de laisser le build le faire : webpack comme Vite peuvent écrire l'attribut `integrity` sur les balises `<script>` et `<link>` qu'ils injectent, et garder chaque hash synchronisé avec le chunk qu'il couvre.

En résumé : ajoutez le plugin [`webpack-subresource-integrity`](https://github.com/waysact/webpack-subresource-integrity) pour [webpack](https://webpack.js.org/concepts/), ou un plugin communautaire tel que [`@small-tech/vite-plugin-sri`](https://github.com/small-tech/vite-plugin-sri) pour [Vite](https://vite.dev/guide/), et les attributs integrity apparaissent automatiquement. Un piège compte : le bundler ne hashe que les chunks qu'il émet. Les scripts tiers que vous chargez depuis un CDN ne sont pas dans le build, ils n'obtiennent donc aucune intégrité, et vous devez toujours les surveiller vous-même.

## Pourquoi l'automatiser [#pourquoi-lautomatiser]

Le SRI est lié aux octets exacts d'un fichier. Changez le fichier, régénérez le hash, sinon le navigateur bloque le chargement. Pour votre propre sortie bundlée, les octets changent à chaque build significatif, et les noms de fichiers sont eux aussi hashés par contenu, donc une liste de hashes maintenue à la main serait fausse en un seul commit.

Câbler le SRI dans le build supprime entièrement cette maintenance pour vos propres assets. Le plugin hashe chaque chunk après son émission et écrit l'attribut `integrity` correspondant dans le HTML ou le manifeste d'assets, pour que le hash et le fichier concordent toujours. [Comment générer un hash Subresource Integrity (SRI)](/fr/blog/generate-sri-hash) couvre la voie manuelle pour les fichiers ponctuels ; cet article est la voie au moment du build pour en gérer beaucoup.

## Webpack [#webpack]

Installez le plugin et ajoutez-le à votre liste de plugins. Il lit quelles fonctions de hash vous voulez et écrit l'attribut `integrity` sur les balises injectées par `html-webpack-plugin`.

```js title="webpack.config.js"
const { SubresourceIntegrityPlugin } = require("webpack-subresource-integrity");

module.exports = {
  output: {
    crossOriginLoading: "anonymous", // required for SRI to be checked
  },
  plugins: [
    new SubresourceIntegrityPlugin({
      hashFuncNames: ["sha384"],
    }),
  ],
};
```

Deux points faciles à manquer. Vous devez régler `output.crossOriginLoading` sur `"anonymous"`, parce que le navigateur ne peut pas vérifier un hash integrity sur un chunk cross-origin récupéré sans CORS, et un bundle servi depuis un CDN est cross-origin. Le plugin émet un avertissement si vous l'oubliez. Deuxièmement, le plugin s'intègre à `html-webpack-plugin` pour estampiller les attributs sur les balises générées ; si vous injectez les scripts autrement, vous lisez les hashes depuis le manifeste d'assets à la place.

### Le piège du code-splitting [#le-piège-du-code-splitting]

C'est la raison pour laquelle un script générique « hasher les fichiers » ne suffit pas. Le code-splitting de webpack produit des chunks importés dynamiquement que le runtime charge à la demande, pas des balises dans votre HTML. Ces chunks se référencent mutuellement, donc le hash d'un chunk enfant fait partie du contenu de son parent, et calculer les hashes dans le mauvais ordre produit des valeurs qui ne correspondent jamais.

`webpack-subresource-integrity` gère cela. Il s'accroche au runtime de webpack pour que les chunks chargés dynamiquement portent et vérifient aussi l'intégrité, et il ordonne le hashing pour que les références inter-chunks se résolvent correctement. Une passe de hashing naïve après le build sur le dossier de sortie ne peut pas faire cela, ce qui explique pourquoi le plugin existe plutôt qu'un one-liner shell.

## Vite [#vite]

Vite ne livre aucun SRI natif, alors utilisez un plugin communautaire. `@small-tech/vite-plugin-sri` calcule les hashes au moment du build et injecte les attributs `integrity` dans le `index.html` émis.

```js title="vite.config.js"
import { defineConfig } from "vite";
import sri from "@small-tech/vite-plugin-sri";

export default defineConfig({
  plugins: [sri()],
});
```

Le plugin s'exécute pendant le build et réécrit les balises de script et de feuille de style avec leurs valeurs integrity. Consultez le readme du plugin pour savoir comment il gère votre disposition d'assets et s'il couvre les chunks importés dynamiquement, car l'écosystème Vite compte plusieurs plugins SRI aux périmètres différents. Comme avec webpack, les assets servis en cross-origin ont toujours besoin que le navigateur les récupère avec CORS pour que le contrôle s'exécute.

## L'angle mort, les scripts de CDN tiers [#langle-mort-les-scripts-de-cdn-tiers]

Voici la partie que les équipes manquent. Le bundler hashe **vos** chunks. Il ne hashe pas les scripts que vous tirez directement d'un CDN tiers, d'un tag manager, d'un snippet d'analytics, d'un widget de paiement, d'un chat embarqué, parce que ceux-là ne passent jamais par le build.

Ces scripts tiers sont exactement ceux qui méritent d'être épinglés, puisque vous ne contrôlez pas le serveur qui les sert. Le bundler ne peut pas aider ici, vous les gérez donc séparément :

* Ajoutez `integrity` et `crossorigin` à chaque balise tierce à la main, en générant la valeur avec le [générateur SRI](/tools/sri-hash), et épinglez une URL versionnée pour que les octets ne bougent pas sous vos pieds.
* Ou exigez l'intégrité sur tout le document avec le header [`Integrity-Policy`](/fr/docs/web-security/policies/integrity-policy), qui bloque les scripts dans le périmètre qui se chargent sans métadonnées d'intégrité (récemment disponible dans les versions actuelles de Chrome, Firefox et Safari).

Dans les deux cas, vous devez d'abord savoir quels scripts tiers vous chargez, et cette liste change à mesure que le marketing et le produit ajoutent des tags au fil du temps. CentralCSP construit un [inventaire de scripts](/platform/supply-chain) de chaque script qui tourne sur vos pages à partir des rapports de hash CSP, pour qu'un fichier tiers nouveau ou modifié apparaisse comme un constat au lieu de se glisser inaperçu. C'est la visibilité que le bundler ne peut pas vous donner, parce que le bundler ne voit que ce qu'il a construit.

## Mettez tout ensemble [#mettez-tout-ensemble]

* Câblez le SRI dans le build pour vos propres assets : `webpack-subresource-integrity` pour webpack, un plugin SRI Vite pour Vite. Réglez le chargement cross-origin sur `anonymous`.
* Laissez le plugin gérer les imports dynamiques code-splittés ; ne bricolez pas votre propre passe de hashing après le build.
* Hashez les scripts de CDN tiers séparément, et suivez ceux que vous chargez pour que la liste ne dérive pas.

Pour voir quel code tiers tourne réellement sur vos pages avant de commencer à l'épingler, [commencez gratuitement](/register) et laissez CentralCSP inventorier vos scripts côté client.

## Sources [#sources]

* [webpack-subresource-integrity, GitHub](https://github.com/waysact/webpack-subresource-integrity)
* [webpack-subresource-integrity, npm](https://www.npmjs.com/package/webpack-subresource-integrity)
* [@small-tech/vite-plugin-sri, GitHub](https://github.com/small-tech/vite-plugin-sri)
* [MDN, Subresource Integrity](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity)

## Articles liés [#articles-liés]

* [Comment générer un hash Subresource Integrity (SRI)](/fr/blog/generate-sri-hash)
* [Subresource Integrity (SRI) expliqué](/fr/blog/subresource-integrity-sri)
* [Référence Subresource Integrity (SRI)](/fr/docs/web-security/other/subresource-integrity)
