Provetry ouvre en novembre 2026. Le test CRA gratuit, les outils et les guides sont disponibles dès maintenant.

SBOM pour les projets npm, pnpm et Yarn pour le CRA

7 min de lecture

Sur cette page
  1. Le fichier de verrouillage fait foi
  2. Produire le SBOM
  3. Ce qui est vraiment livré
  4. Les pièges propres à npm
  5. Du SBOM aux vulnérabilités
  6. Ce que fait Provetry
  7. Sources

Le Cyber Resilience Act demande à chaque fabricant de tenir une nomenclature des logiciels « dans un format couramment utilisé et lisible par machine couvrant au moins les dépendances de niveau supérieur des produits » (annexe I, partie II, point 1). Pour un produit JavaScript ou TypeScript, presque tout ce qu’il faut se trouve déjà dans votre fichier de verrouillage. Le plus délicat est de savoir lesquels des centaines de paquets de node_modules sont vraiment livrés. Ce guide traite de cette question, et des commandes qui en font un fichier CycloneDX ou SPDX.

Pour le règlement lui-même, voir Le SBOM pour le Cyber Resilience Act.

Le fichier de verrouillage fait foi

package.json dit ce que vous avez demandé, avec des plages (^4.19.0). Seul le fichier de verrouillage dit ce qui a été installé : la version exacte de chaque paquet, direct ou transitif, et en général son empreinte.

Gestionnaire Fichier de verrouillage Dépendances directes enregistrées dans
npm package-lock.json (ou npm-shrinkwrap.json) le fichier de verrouillage lui-même
pnpm pnpm-lock.yaml le fichier de verrouillage lui-même
Yarn (classique et Berry) yarn.lock package.json seulement

Versionnez le fichier de verrouillage et installez avec npm ci, pnpm install --frozen-lockfile ou yarn install --immutable dans votre build. Sinon, le SBOM décrit une installation et le produit en contient une autre.

Produire le SBOM

npm a une commande intégrée depuis la version 9.5 :

npm sbom --sbom-format cyclonedx --sbom-type application --omit dev > sbom.cdx.json

Elle lit node_modules par défaut ; ajoutez --package-lock-only pour partir du seul fichier de verrouillage, par exemple avant l’installation. --sbom-format spdx écrit du SPDX 2.3. La sortie CycloneDX est en version 1.5.

pnpm a ajouté sa propre commande avec la version 11, qui écrit du CycloneDX 1.7 ou du SPDX 2.3 :

pnpm sbom --sbom-format cyclonedx --sbom-type application --prod > sbom.cdx.json

Pour Yarn, ou pour un monorepo qui mélange plusieurs gestionnaires, le générateur cdxgen du projet CycloneDX les lit tous :

npx @cyclonedx/cdxgen -t js -o sbom.cdx.json

Quel que soit l’outil, indiquez --sbom-type application (ou son équivalent) quand le produit est une application et non une bibliothèque, et donnez au composant racine le nom et la version du produit que vous mettez sur le marché, pas ceux du dépôt.

Ce qui est vraiment livré

Le CRA porte sur le produit tel qu’il est livré : la question n’est pas « qu’y a-t-il dans node_modules ? » mais « qu’est-ce qui arrive chez le client ? ». La réponse dépend du type de produit.

  • Un service ou un outil en ligne de commande Node.js que vous distribuez. Ce qui est livré, c’est l’arbre de production : dependencies et leurs dépendances. Laisser de côté les devDependencies (--omit dev, --prod) donne la bonne liste, à condition que l’équipe garde les outils de test et de build hors de dependencies.
  • Un bundle front-end (une application construite avec Vite, webpack, esbuild ou autre). Le bundler recopie le code des paquets dans les fichiers livrés, et beaucoup de projets déclarent ces paquets en devDependencies, puisque rien n’est installé à l’exécution. Ici, --omit dev retirerait React ou Vue du SBOM. Gardez sous dependencies tout ce qui finit dans le bundle, ou décrivez le bundle lui-même avec un outil qui le lit, et gardez les dépendances de développement marquées comme telles plutôt que supprimées.
  • Une application Electron ou de bureau. Elle livre l’environnement d’exécution Electron, avec son propre Chromium et son propre Node.js. La version d’Electron a sa place dans le SBOM, et ses correctifs de sécurité comptent autant que ceux de vos paquets npm. Electron est en général une devDependency : --omit dev le retire, donc rajoutez-le, ou produisez le SBOM sans écarter les dépendances de développement.

Les dépendances de développement méritent quand même d’être consignées. Un outil de build compromis peut altérer ce que vous livrez, et CycloneDX permet de les garder dans le fichier, marquées comme exclues du produit.

Les pièges propres à npm

  • Les scripts d’installation exécutent du code. Tout paquet doté d’un script preinstall ou postinstall s’exécute pendant npm install, sur les postes des développeurs comme en CI. C’est ainsi que le ver Shai-Hulud s’est propagé sur npm en 2025, en volant les jetons des machines qui installaient les paquets infectés. npm ci --ignore-scripts en CI, ou pnpm, qui n’exécute pas les scripts de build des dépendances sans votre accord, limitent le risque.
  • Plusieurs versions d’un même paquet. npm peut installer lodash trois fois, en trois versions. Les trois ont leur place dans le SBOM, et chacune doit être vérifiée.
  • Les workspaces. Dans un monorepo, produisez un SBOM par produit mis sur le marché, pas un pour tout le dépôt.
  • Les dépendances Git et locales (file:) (github:org/repo#commit, file:../lib) n’ont pas de version du registre. Donnez-leur une version et une source que le SBOM peut porter, sans quoi aucune base de vulnérabilités ne les reconnaîtra.

Du SBOM aux vulnérabilités

npm audit compare le fichier de verrouillage à la base d’avis de GitHub, et tout scanner qui lit CycloneDX lit le SBOM. Pour le CRA, deux choses comptent au-delà de la liste brute :

  • Les failles exploitées d’abord. Une vulnérabilité inscrite au catalogue KEV de la CISA ou dans la base européenne des vulnérabilités est un indice fort d’exploitation active ; dès que vous savez qu’une telle faille est dans votre produit, l’article 14 vous laisse 24 heures pour une alerte précoce. Voir CVSS, EPSS et KEV.
  • Atteignable ou non. La plupart des fonctions vulnérables d’un arbre node_modules ne sont jamais appelées par votre code. Consignez votre évaluation dans une déclaration VEX, avec sa justification, plutôt que de laisser la faille ouverte.

Ce que fait Provetry

Provetry lit package-lock.json, npm-shrinkwrap.json, pnpm-lock.yaml (versions 6 et 9 du format) et yarn.lock (classique et Berry) depuis votre CI ou dans les fichiers que vous envoyez, distingue les dépendances directes des transitives, et établit le SBOM de chaque version en CycloneDX, et en SPDX avec les offres payantes. Il surveille chaque jour avec les offres payantes et chaque semaine avec l’offre gratuite chaque composant pour les vulnérabilités nouvelles et exploitées. Son étape de CI cherche la preuve qu’un paquet vulnérable n’est jamais chargé ; avec les offres Pro et Consultant, il descend jusqu’à la fonction vulnérable pour npm. Avec les fichiers de verrouillage de npm et de pnpm, qui les signalent, les paquets dotés d’un script d’installation comptent toujours comme chargés. Chaque résultat est une suggestion accompagnée de sa preuve, que vous acceptez ou non.

Sources