Le rapport OSSRA 2026 (Synopsys) ne laisse aucune place au doute : les attaques ciblant la supply chain npm ont doublé en un an, avec désormais 581 vulnérabilités par codebase en moyenne et 87 % des bases de code auditées exposées à au moins un risque lié à leurs dépendances open source. Les incidents de 2025-2026 — de la compromission de packages TanStack à l'attaque Injective Labs — montrent que n'importe quel projet JavaScript, de la startup au grand groupe, peut devenir une cible.

La bonne nouvelle : se protéger efficacement ne demande ni budget faramineux ni expertise pointue en sécurité. Ce guide vous donne 7 étapes concrètes, ordonnées de la plus fondamentale à la plus complète, pour transformer votre pipeline en forteresse. Chaque étape inclut des commandes prêtes à copier-coller et des fichiers de configuration complets.

Pour comprendre comment ces chiffres ont évolué, consultez notre analyse du rapport OSSRA 2026.

Étape 1 : Verrouiller le lockfile avec npm ci et versions pinées

La première barrière de sécurité est aussi la plus simple à mettre en place. Le fichier package-lock.json fige les versions exactes de chaque dépendance (directe et transitive) et stocke les hashs d'intégrité SHA-512 de chaque tarball. Sans ce verrou, un attaquant peut publier une version malveillante sous un numéro de version identique et votre prochaine installation la récupère silencieusement.

Remplacer npm install par npm ci

En production et en CI, la règle est absolue : utilisez toujours npm ci. Contrairement à npm install, cette commande supprime l'intégralité du dossier node_modules, installe uniquement ce que le lockfile décrit et échoue immédiatement si le lockfile est désynchronisé de package.json. Aucune mise à jour silencieuse n'est possible.

# En CI : toujours npm ci, jamais npm install
npm ci

# Pinner les versions dans package.json (pas de ^ ni ~)
npm config set save-exact true

# Vérifier que le lockfile est bien commité
git diff --exit-code package-lock.json || echo "ERREUR: lockfile non commité"

# Ajouter au .npmrc du projet
echo "save-exact=true" >> .npmrc
echo "package-lock=true" >> .npmrc

Committez systématiquement package-lock.json dans votre dépôt Git. Ajoutez une règle dans votre CI qui refuse la fusion si le lockfile a été modifié sans passer par npm ci. Cette seule mesure aurait bloqué la quasi-totalité des attaques par confusion de dépendances (dependency confusion) documentées en 2025.

Complétez la protection avec lockfile-lint, un outil qui vérifie que votre lockfile ne référence que des registres autorisés et utilise le protocole HTTPS :

# Installer lockfile-lint
npm install --save-dev lockfile-lint

# Vérification en une commande
npx lockfile-lint --path package-lock.json --type npm \
  --allowed-hosts npm --validate-https --validate-integrity

Étape 2 : Bloquer les scripts lifecycle avec pnpm v11

La majorité des attaques supply chain npm exploitent un même vecteur : les scripts postinstall. Un package malveillant enregistre un script qui s'exécute automatiquement après l'installation — exfiltration de tokens, installation de backdoors, lecture de .env. Jusqu'ici, la parade consistait à ajouter ignore-scripts=true dans .npmrc, mais cette configuration cassait les packages légitimes nécessitant une compilation native (comme sharp, bcrypt ou sqlite3).

pnpm v11, sorti en avril 2026, résout ce dilemme avec une approche par allowlist. Par défaut, tous les lifecycle scripts de dépendances tierces sont bloqués. Seuls les packages explicitement autorisés peuvent exécuter leurs scripts de build :

# package.json — allowlist pnpm v11
{
  "pnpm": {
    "onlyBuiltDependencies": [
      "sharp",
      "bcrypt",
      "better-sqlite3",
      "esbuild"
    ]
  }
}

# Installer pnpm v11
corepack enable
corepack prepare pnpm@11 --activate

# Vérifier que les scripts sont bien bloqués
pnpm install --reporter=default 2>&1 | grep "skipped lifecycle"

Si vous ne pouvez pas migrer vers pnpm immédiatement, reproduisez ce comportement avec npm en ajoutant ignore-scripts=true dans .npmrc et en exécutant manuellement les scripts nécessaires après l'installation :

# .npmrc — désactiver tous les scripts
ignore-scripts=true

# Après npm ci, exécuter uniquement les scripts nécessaires
npm rebuild sharp
npm rebuild bcrypt

« Le blocage par défaut des lifecycle scripts dans pnpm v11 est le changement de sécurité le plus significatif dans l'écosystème npm depuis l'introduction des provenance attestations. Il inverse le modèle de confiance : au lieu d'autoriser tout et d'espérer que rien n'est malveillant, on bloque tout et on autorise explicitement. C'est exactement le principe du moindre privilège appliqué aux dépendances. »

— Analyse basée sur la RFC pnpm v11 et les retours de la communauté (avril 2026)

Étape 3 : Déployer un dépôt privé comme gardien (Nexus / Artifactory)

Pointer directement vers registry.npmjs.org signifie que chaque npm install fait confiance au registre public pour servir du code non compromis. Un dépôt privé (Sonatype Nexus Repository ou JFrog Artifactory) s'intercale comme un gardien entre votre équipe et le registre public. Il agit comme un proxy-cache intelligent qui :

  • Met en cache les packages approuvés localement — un package supprimé du registre (left-pad, bis) reste disponible
  • Applique des politiques de sécurité : interdiction des nouvelles versions non vérifiées, analyse antivirale, conformité licence
  • Bloque les attaques par confusion de dépendances en contrôlant les scopes et les noms de packages
  • Fournit un historique d'audit complet : qui a installé quoi et quand
# .npmrc — pointer vers votre dépôt Nexus
registry=https://nexus.votre-entreprise.fr/repository/npm-group/
always-auth=true
//nexus.votre-entreprise.fr/repository/npm-group/:_authToken=${NPM_TOKEN}

# Pour les packages internes avec scope
@votre-org:registry=https://nexus.votre-entreprise.fr/repository/npm-private/

# --- Configuration Nexus (résumé) ---
# 1. Créer un "npm proxy" pointant vers https://registry.npmjs.org
# 2. Créer un "npm hosted" pour vos packages internes
# 3. Créer un "npm group" combinant proxy + hosted
# 4. Activer la politique "Block outbound" pour les nouvelles versions non scannées

Si Nexus ou Artifactory sont trop lourds pour votre infrastructure, Verdaccio offre une alternative légère et open source que vous pouvez déployer en 10 minutes avec Docker. Il couvre les besoins de cache et de contrôle d'accès pour les équipes de taille moyenne.

Architecture : dépôt privé comme gardien supply chainDéveloppeurnpm ci / pnpm installCI / CDGitHub ActionsNexus / ArtifactoryProxy-cache + politiquesnpmjs.orgRegistre publicPackage compromisBloqué par politiquePackages internes@votre-org/*AutoriséBloquéProxy (vérifié)

Étape 4 : Activer le Trusted Publishing et la provenance npm

Le Trusted Publishing transforme la publication npm en un processus vérifiable cryptographiquement. Chaque package publié via un workflow CI (GitHub Actions, GitLab CI) reçoit une attestation de provenance Sigstore qui lie le tarball au commit exact et au workflow qui l'a construit. Côté consommateur, cette provenance apparaît sous la forme d'un badge vert « Provenance » sur la page npm du package.

Pour vos propres packages, activez la provenance en une ligne :

# Publier avec provenance (GitHub Actions)
- name: Publish to npm
  run: npm publish --provenance --access public
  env:
    NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

# Le workflow doit avoir les permissions id-token: write
permissions:
  contents: read
  id-token: write

Côté consommateur, vérifiez systématiquement les signatures de vos dépendances :

# Vérifier les signatures de toutes les dépendances installées
npm audit signatures

# Résultat typique (août 2026) :
# 1247 packages have verified registry signatures
# 389 packages have verified attestations
# 0 packages have missing or invalid signatures

# Vérifier la provenance d'un package spécifique
npm view express --json | jq '.attestations'

Intégrez npm audit signatures dans votre pipeline CI comme étape bloquante. Si un package perd sa signature entre deux builds, c'est un signal d'alerte critique qui doit stopper le déploiement immédiatement.

Besoin d'un audit sécurité supply chain pour votre équipe ?

Nos ingénieurs analysent vos dépendances, déploient un dépôt privé et configurent une défense automatisée en moins d'une journée.

Demander un audit gratuit

Étape 5 : Scanner avec Socket.dev et npm audit en CI

Les scanners de vulnérabilités classiques (npm audit, osv-scanner) détectent les CVE connues — des failles déjà documentées et indexées. Le problème : dans une attaque supply chain, le code malveillant est inséré intentionnellement et ne correspond à aucune CVE existante au moment de l'attaque. Socket.dev comble cette lacune en analysant le comportement du code plutôt que sa réputation.

Socket examine chaque mise à jour et détecte les signaux suspects : accès réseau inattendu, lecture de process.env, exécution de child_process, obfuscation, installation de binaires. Cette analyse aurait détecté les 18 packages Injective Labs compromis dès leur publication.

Combiner les deux approches en CI

# .github/workflows/npm-security.yml
name: npm Security Gates

on:
  pull_request:
    paths: ['package.json', 'package-lock.json', 'pnpm-lock.yaml']
  push:
    branches: [main]
  schedule:
    - cron: '0 7 * * 1'  # Chaque lundi 7h — nouvelles CVE du week-end

jobs:
  security:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      id-token: write
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '22'
          cache: 'npm'

      - name: Install (locked)
        run: npm ci

      # 1. Vérification des signatures de provenance
      - name: Verify provenance signatures
        run: npm audit signatures

      # 2. Scan CVE (high + critical uniquement)
      - name: CVE audit
        run: npm audit --audit-level=high

      # 3. Analyse comportementale Socket
      - name: Socket.dev scan
        uses: SocketDev/socket-security-action@v1
        with:
          repo-token: ${{ secrets.GITHUB_TOKEN }}

      # 4. osv-scanner pour couverture élargie
      - name: OSV scan
        run: npx osv-scanner --lockfile=package-lock.json

Le plan gratuit de Socket couvre les dépôts publics sans limite. En complément, npm audit avec --audit-level=high filtre le bruit des vulnérabilités basses et modérées pour ne garder que les alertes exploitables.

Pipeline CI/CD — 7 portes de sécurité supply chainnpm ciLockfileScriptsAllowlistNexusProxyProvenanceSigstoreSocketBehaviorSBOMCycloneDXDeploy🚀Porte échouée = Pipeline bloquéNotification Slack + email immédiateValidation réussieAlerte critiqueToutes portes passées

Étape 6 : Générer un SBOM conforme CISA (SPDX / CycloneDX)

Un SBOM (Software Bill of Materials) est l'inventaire exhaustif de tous les composants de votre application : dépendances directes, transitives, versions, licences et hashs d'intégrité. La guidance CISA de 2025 sur les SBOM pour la sécurité de la supply chain logicielle recommande explicitement les formats SPDX et CycloneDX. En Europe, le Cyber Resilience Act (CRA) et NIS2 rendent le SBOM de facto obligatoire pour tout logiciel déployé dans l'UE.

Générer un SBOM CycloneDX depuis npm

# Installer l'outil officiel CycloneDX pour npm
npm install --save-dev @cyclonedx/cyclonedx-npm

# Générer le SBOM au format JSON
npx @cyclonedx/cyclonedx-npm --output-file sbom.cdx.json

# Générer au format XML (pour outils compliance legacy)
npx @cyclonedx/cyclonedx-npm --output-file sbom.cdx.xml --output-reproducible

# Valider le SBOM généré contre le schéma CycloneDX
npx @cyclonedx/cyclonedx-npm --validate

Alternative SPDX avec syft

Si votre client ou votre secteur (automobile, aéronautique, défense) exige le format SPDX, l'outil syft d'Anchore produit les deux formats :

# Installer syft
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s

# SBOM SPDX depuis le répertoire projet
syft dir:. -o spdx-json=sbom.spdx.json

# SBOM CycloneDX (alternative)
syft dir:. -o cyclonedx-json=sbom.cdx.json

# Scanner le SBOM contre les CVE avec grype
grype sbom:sbom.cdx.json --fail-on high

Intégrez la génération du SBOM comme artefact de build dans votre pipeline CI. Associez-le à chaque release et stockez-le dans votre dépôt d'artefacts (Nexus, Artifactory ou GitHub Releases). En cas de nouvelle CVE sur une dépendance transitive, vous identifierez en quelques secondes tous les projets affectés en scannant vos SBOM archivés avec grype.

« Le SBOM n'est plus un exercice de conformité théorique. Avec 581 vulnérabilités par codebase selon l'OSSRA 2026 et la guidance CISA 2025 qui fait référence, c'est devenu un outil opérationnel indispensable. Quand la prochaine vulnérabilité critique tombe un vendredi soir, la différence entre « on cherche pendant 48 heures quels projets sont touchés » et « on a la liste en 30 secondes » se joue dans vos SBOM. »

— Analyse basée sur la guidance CISA SBOM 2025 et le rapport OSSRA 2026

Étape 7 : Corriger les dépendances transitives avec overrides

Le scénario classique : npm audit signale une vulnérabilité critique dans lodash@4.17.20, utilisée par une dépendance transitive de troisième niveau. Le mainteneur du package intermédiaire n'a pas mis à jour depuis 8 mois. Vous ne pouvez pas forcer la mise à jour sans casser la compatibilité. C'est là qu'interviennent les overrides de package.json.

Les overrides vous permettent de forcer une version spécifique d'une dépendance transitive, sans attendre que le mainteneur du package parent mette à jour. C'est un patch chirurgical qui résout le problème immédiatement :

{
  "overrides": {
    // Forcer la version corrigée de semver (CVE-2022-25883)
    "semver": ">=7.5.4",

    // Corriger tough-cookie dans toute la chaîne
    "tough-cookie": ">=4.1.3",

    // Forcer word-wrap corrigé
    "word-wrap": ">=1.2.4",

    // Override ciblé : corriger axios uniquement dans react-scripts
    "react-scripts": {
      "axios": ">=1.7.4"
    },

    // Override profond : corriger une dépendance de dépendance
    "webpack>watchpack>chokidar": ">=3.6.0"
  }
}

Quelques règles essentielles pour utiliser les overrides de manière sûre :

  • Documentez chaque override avec un commentaire expliquant la CVE concernée et la date d'ajout. Les overrides oubliés deviennent de la dette technique invisible.
  • Testez systématiquement après chaque ajout. Un override peut casser un package si l'API de la dépendance forcée a changé entre les versions.
  • Retirez les overrides dès que le mainteneur du package parent publie une version corrigée. Exécutez npm audit mensuellement pour identifier les overrides devenus inutiles.
  • Pour pnpm, utilisez le champ équivalent pnpm.overrides dans package.json. Pour yarn, utilisez resolutions.
# Vérifier que les overrides ont bien pris effet
npm ls semver
# semver@7.6.3 (overridden)

# Script de maintenance : lister les overrides actifs et vérifier s'ils sont encore nécessaires
node -e "
const pkg = require('./package.json');
const overrides = pkg.overrides || {};
console.log('Overrides actifs :', Object.keys(overrides).length);
Object.entries(overrides).forEach(([dep, ver]) => {
  console.log('  ' + dep + ' -> ' + (typeof ver === 'string' ? ver : JSON.stringify(ver)));
});
"

Conclusion : 7 couches de défense contre une menace qui double chaque année

Avec 581 vulnérabilités par codebase et des attaques supply chain qui doublent d'une année sur l'autre, la sécurité des dépendances npm n'est plus un « nice to have » — c'est une exigence opérationnelle. Les 7 étapes de ce guide construisent une défense en profondeur : chaque couche compense les faiblesses de la précédente, de la vérification d'intégrité du lockfile jusqu'aux overrides chirurgicaux des dépendances transitives.

L'investissement est modéré : moins d'une heure pour la configuration initiale, zéro maintenance une fois le pipeline CI/CD en place. Le retour est immédiat : chaque pull request est automatiquement scannée, chaque dépendance suspecte est bloquée avant d'atteindre la production. Plus important encore, en cas d'incident, votre SBOM vous permet d'identifier les projets affectés en quelques secondes plutôt qu'en quelques jours.

Pour aller plus loin, découvrez notre guide complet pour sécuriser un pipeline CI/CD et notre analyse du rapport Verizon DBIR 2026 sur les attaques supply chain.

Protégez votre supply chain npm dès aujourd'hui

Nos ingénieurs infrastructure configurent l'ensemble du pipeline en moins d'une journée : lockfile, pnpm v11, dépôt privé, provenance, Socket, SBOM et monitoring continu.

Configurer ma sécurité supply chain

Questions fréquentes

Combien de vulnérabilités open source touche une codebase en moyenne en 2026 ?

Selon le rapport OSSRA 2026 (Synopsys), une codebase contient en moyenne 581 vulnérabilités connues dans ses dépendances open source, soit le double par rapport à 2024. 87 % des bases de code auditées présentent au moins un risque lié à la supply chain. Ce chiffre reflète à la fois l'augmentation du nombre de CVE publiées et la croissance continue des arbres de dépendances dans les projets JavaScript modernes.

pnpm v11 bloque-t-il vraiment les scripts postinstall par défaut ?

Oui. Depuis sa sortie en avril 2026, pnpm v11 désactive les lifecycle scripts (preinstall, install, postinstall) pour toutes les dépendances tierces. Seuls les scripts déclarés dans une allowlist explicite via pnpm.onlyBuiltDependencies dans package.json sont exécutés. Ce changement bloque le vecteur d'attaque le plus répandu dans les compromissions npm sans casser les packages légitimes qui nécessitent une compilation native, à condition de les déclarer.

Un dépôt Nexus ou Artifactory est-il nécessaire pour un petit projet ?

Pour un projet personnel ou une petite équipe de moins de 5 développeurs, un dépôt privé n'est pas indispensable : le lockfile, npm ci, Socket.dev et les overrides couvrent l'essentiel. Dès que vous gérez plusieurs projets en entreprise, publiez des packages internes avec un scope @org, ou devez répondre à des exigences de conformité (NIS2, CRA), un dépôt comme Nexus ou Artifactory devient un investissement rentable. Pour les équipes intermédiaires, Verdaccio offre une alternative légère déployable en 10 minutes avec Docker.

Quel format de SBOM choisir : SPDX ou CycloneDX ?

Les deux formats sont acceptés par la CISA (guidance 2025). CycloneDX est plus populaire dans l'écosystème JavaScript grâce à l'outil @cyclonedx/cyclonedx-npm officiel et bénéficie d'un support natif dans de nombreux outils de sécurité (grype, Dependency-Track). SPDX est privilégié dans les secteurs automobile, aéronautique et défense. Concrètement, choisissez le format demandé par votre client ou votre réglementation. En l'absence de contrainte spécifique, CycloneDX offre le chemin d'intégration le plus simple pour les projets npm.

Articles similaires

Sources

  • • Synopsys — Open Source Security and Risk Analysis (OSSRA) Report 2026
  • • CISA — Software Bill of Materials (SBOM) Guidance, 2025
  • • npm Documentation — Provenance attestations, npm audit signatures, npm ci
  • • pnpm v11 Release Notes — Blocked lifecycle scripts by default (avril 2026)
  • • Socket.dev — Documentation technique et analyse comportementale
  • • Sigstore — Keyless signing et Trusted Publishing pour npm
  • • CycloneDX / SPDX — Spécifications SBOM et outils de génération
  • • Commission européenne — Cyber Resilience Act (CRA) et directive NIS2