123% de CVE signalées en plus par jour en 2026 par rapport à l'an dernier.

Red team vs blue team

Attaques de la chaîne d'approvisionnement : comment les attaquants entrent, et comment les arrêter

Les attaquants ciblent rarement votre entreprise. Ils ciblent le paquet, l'Action ou l'outil de build dont dépendent les entreprises du monde entier, puis essaient l'exploit sur toutes à la fois. Ils n'ont pas besoin de votre liste de dépendances. Vous, si.

Qu'est-ce qu'une attaque de la chaîne d'approvisionnement logicielle ?

Une attaque de la chaîne d'approvisionnement logicielle compromet un élément à partir duquel un produit est construit, comme un paquet open source, un composant CI/CD ou le système de build, au lieu d'attaquer directement le produit. Les logiciels modernes sont pour l'essentiel du code écrit par d'autres : la majeure partie vient de paquets open source, et la plupart de ceux-ci sont des dépendances transitives que personne dans l'équipe n'a choisies. Compromettez un composant largement utilisé, et vous atteignez toutes les organisations qui s'appuient sur lui.

Cela change la façon dont les attaquants choisissent leurs cibles. Ils n'étudient pas les dépendances d'une entreprise. Ils choisissent un paquet ou un outil très répandu, puis l'exploitent partout et regardent ce qui répond.

Types d'attaques de la chaîne d'approvisionnement logicielle

Exploitation d'une dépendance vulnérable

Une faille dans un paquet open source populaire est divulguée, et les attaquants l'exploitent dans tous les produits qui livrent la version vulnérable, généralement en tant que dépendance transitive que personne n'a choisie directement.

Releases de paquets malveillantes

Un attaquant prend le contrôle d'un compte de mainteneur, ou un ver vole des tokens de publication, et publie une version empoisonnée d'un paquet de confiance. Elle s'exécute dès qu'un build l'installe, comme avec le ver npm Shai-Hulud.

Projets amont piégés par une porte dérobée

Un contributeur gagne peu à peu la confiance d'un projet open source, puis glisse du code malveillant dans une release que reprennent les distributions et les produits en aval, comme avec la porte dérobée de xz utils.

Typosquatting et confusion de dépendances

Des paquets aux noms proches de ceux de paquets populaires profitent des fautes de frappe. La confusion de dépendances va plus loin : un paquet public portant le même nom qu'un paquet interne d'une entreprise est installé à sa place.

Composants CI/CD compromis

Une GitHub Action ou un autre outil de build est détourné, et chaque pipeline qui l'utilise exécute le code de l'attaquant avec ses secrets à portée de main, comme avec tj-actions et Codecov.

Altération du build et des artefacts

Le build lui-même est modifié, ou l'artefact est substitué entre le build et le déploiement : un arbre source sain produit alors tout de même une release compromise, comme avec SolarWinds.

Exemples d'attaques de la chaîne d'approvisionnement

SolarWinds est l'attaque de la chaîne d'approvisionnement la plus connue : du code malveillant inséré au build et livré aux clients comme une mise à jour normale. Les attaques les plus récentes visent plutôt les registres de paquets et les pipelines CI, où un seul paquet ou une seule Action compromis atteint tous les builds qui l'utilisent. Du plus récent au plus ancien :

ver npm · depuis septembre 2025

Shai-Hulud

Un ver auto-propagatif qui s'exécute à l'installation d'un paquet npm infecté, vole des tokens npm, GitHub et cloud, et publie des versions infectées des autres paquets de la victime. La plupart des infections se sont produites en CI.

Comment vérifier vos builds →

CVE-2025-30066 · mars 2025

tj-actions/changed-files

La CISA a indiqué que toutes les versions de cette GitHub Action populaire avaient été compromises pendant trois jours, avec des secrets exposés dans les logs de workflow. Les workflows qui la référençaient par tag ont exécuté le code de l'attaquant.

CVE-2024-3094 · mars 2024

Porte dérobée de xz utils

Andres Freund a découvert une porte dérobée dans les versions 5.6.0 et 5.6.1 de xz après avoir remarqué que les connexions SSH consommaient trop de CPU. Elle avait été introduite dans le projet amont lui-même.

CVE-2021-44228 · décembre 2021

Log4Shell

Une faille dans Apache Log4j 2 permettait à un attaquant contrôlant un message journalisé d'exécuter du code arbitraire, avec un score CVSS de 10.0. Pour la plupart des équipes, la difficulté a été de trouver quelles applications contenaient log4j-core, généralement en tant que dépendance d'une dépendance.

janvier à avril 2021

Codecov Bash Uploader

Des attaquants ont modifié le script Bash Uploader que les équipes exécutaient dans leurs pipelines CI, afin qu'il envoie l'environnement CI, y compris les identifiants, tokens et clés, à un serveur extérieur à l'infrastructure de Codecov. Cela a fonctionné sans être remarqué du 31 janvier jusqu'au signalement d'un client, le 1er avril.

SUNBURST · décembre 2020

SolarWinds Orion

Des attaquants disposaient depuis longtemps d'un accès dissimulé au processus de build de SolarWinds Orion et ont inséré du code malveillant dans les releases 2019.4 à 2020.2.1 HF1 d'Orion, que les clients ont installées comme des mises à jour normales. La CISA a publié une directive d'urgence en réponse.

Red team vs blue team

Comment fonctionnent les attaques de la chaîne d'approvisionnement, étape par étape

Chaque étape avec les mots de l'attaquant, et la défense qui y répond.

Étape 1 sur 3

Reconnaissance

Inutile de connaître la cible. Choisissez le paquet, et les cibles se désignent d'elles-mêmes.

Red team

Misez sur les dépendances que tout le monde utilise

Vous n'avez pas besoin de leur lockfile. Les paquets populaires se trouvent au fond de l'arbre transitif de presque tout, et la plupart des équipes ne savent pas dire lesquels elles livrent. Des indices publics réduisent le champ : versions dans les bundles JavaScript et les en-têtes HTTP, dépôts publics et images de conteneur. Et tout ce que leur build récupère en dehors du lockfile, comme le binaire téléchargé par un script postinstall ou les couches sous leur image de base, leur scanner ne l'a jamais vu : personne ne le corrige donc.

Blue team

Connaissez chaque dépendance récupérée par chaque build

CRACI voit le trafic qui entre dans chaque build et enregistre chaque paquet et fichier récupéré, y compris les dépendances cachées que les outils basés sur les lockfiles manquent, à tous les niveaux de l'arbre transitif. Votre SBOM vient du build qui a été livré : vous disposez donc de la liste dont un attaquant n'a jamais eu besoin, avant que quiconque se mette à chercher.

SBOM au build →

Red team

Passez à l'action dès qu'une nouvelle CVE tombe

Un nouvel avis de sécurité vous dit exactement quelles versions sont vulnérables. Construisez l'exploit, scannez tout ce qui répond et laissez le scan vous dire qui ils sont. Vous commencez le jour même, pendant que leur équipe demande encore « sommes-nous touchés ? » dans un fil Slack.

Blue team

« Sommes-nous touchés ? » : la réponse dans l'enregistrement du build

CRACI réévalue en continu les SBOM surveillées par rapport aux nouvelles données de vulnérabilité. L'historique des builds montre quels builds contenaient la dépendance vulnérable, directe ou transitive : vous savez ainsi où elle a été livrée et pendant combien de temps.

Sommes-nous touchés ? →

Étape 2 sur 3

Entrer

Exploitez la faille avant qu'elle soit corrigée, ou oubliez la faille et empruntez leur pipeline.

Red team

Générez l'attaque le jour de la divulgation

L'IA transforme un avis de sécurité et un diff de correctif en attaque fonctionnelle avant que leur équipe sécurité ait trié le ticket. La divulgation est votre coup d'envoi. Leur planification de sprint a lieu la semaine prochaine.

Blue team

Cessez de livrer la version vulnérable

Les gates de politique peuvent bloquer tout build qui contient une CVE précise : la version vulnérable cesse donc d'être livrée dès que vous le décidez, quelle que soit sa profondeur dans l'arbre.

Remédiation des CVE →

Red team

Réécrivez un tag, tournez dans mille pipelines

Les workflows font confiance à des tags comme @v4, et les tags peuvent être déplacés. Compromettez une GitHub Action populaire et chaque workflow qui l'utilise exécute votre code, avec ses secrets à portée de main.

Blue team

Sachez exactement quelle Action chaque build a exécutée

CRACI enregistre les GitHub Actions exécutées par un workflow dans la SBOM du build, épinglées au commit réellement exécuté. Lorsqu'une Action est compromise, vous voyez quels builds ont exécuté le mauvais code au lieu de le deviner à partir d'un tag.

Checklist de sécurité CI/CD →

Étape 3 sur 3

Sortir

Prenez les secrets et restez pour la suite.

Red team

Contactez votre serveur depuis leur CI

Une release de paquet malveillante exécute son script d'installation dans leur build, là où se trouvent les tokens et les identifiants cloud. Les runners CI peuvent généralement atteindre tout Internet : les secrets partent donc vers votre serveur avant que quiconque sache que le paquet est mauvais.

Blue team

Un build n'atteint que ce dont il a besoin

Une politique de trafic sortant en refus par défaut laisse un build atteindre ses sources de paquets et ses cibles de publication, et bloque tout le reste. Un malware qui envoie vos secrets vers l'hôte d'un attaquant est bloqué, même en tant que patient zéro d'une attaque que personne n'a encore vue, et vous recevez une alerte sur la violation de politique.

Politiques de trafic sortant →

Red team

Restez sur le runner pour le job suivant

Les runners auto-hébergés à longue durée de vie sont un cadeau : déposez quelque chose dans le workspace ou le cache d'outils et attendez que le job suivant, et le prochain lot de secrets, vienne à vous.

Blue team

Une machine virtuelle isolée par job

Chaque job CRACI s'exécute dans sa propre machine virtuelle isolée : rien de ce qu'un job laisse derrière lui n'attend le suivant. Vous n'avez pas non plus de flotte de runners à corriger et à durcir.

Runners managés ou auto-hébergés →

Après la divulgation

La course commence quand l'avis de sécurité devient public

L'attaquant n'a pas besoin de savoir que vous utilisez la dépendance. Il essaie l'exploit partout et regarde ce qui répond. Votre équipe a besoin de savoir où cette dépendance a été livrée. Toute la différence est de savoir si vous devez aller chercher, et il y a chaque année plus de courses à disputer : voir combien de CVE sont publiées chaque jour.

Red team

  1. Avis de sécurité publié
  2. Exploit généré
  3. Scan de tout ce qui exécute une version vulnérable
  4. Dans chaque cible trouvée, y compris la vôtre

Blue team, sans enregistrement du build

  1. Avis de sécurité publié
  2. « Sommes-nous touchés ? »
  3. Grep dans les dépôts, lockfiles et images
  4. Trouver la copie transitive que personne n'a listée
  5. Déterminer quelles releases l'ont livrée
  6. Corriger

Blue team, avec CRACI

  1. Avis de sécurité publié
  2. SBOM surveillées réévaluées
  3. L'historique des builds montre les builds et la période
  4. Une gate de politique bloque les nouveaux builds avec la CVE

Comment prévenir les attaques de la chaîne d'approvisionnement logicielle

Aucun contrôle n'arrête à lui seul toutes les attaques de la chaîne d'approvisionnement. Superposez ceux qui suivent, et chaque étape ci-dessus devient plus difficile. Pour le détail côté pipeline, consultez la checklist de sécurité des pipelines CI/CD.

  1. Sachez ce que livre chaque build. Conservez une SBOM pour chaque build, y compris les dépendances transitives et tout ce qui est récupéré en dehors du lockfile. Un scan du dépôt n'est pas un enregistrement de la release.
  2. Surveillez ce qui a été livré, pas seulement la branche par défaut. Revérifiez les builds publiés par rapport aux nouveaux avis de sécurité, et conservez l'historique des builds qui vous indique depuis quand vous êtes exposé.
  3. Épinglez les dépendances et les Actions. Utilisez des lockfiles et épinglez les GitHub Actions à un SHA de commit complet. GitHub présente cela comme le seul moyen d'utiliser une action en tant que release immuable.
  4. Arrêtez les versions vulnérables au build. Conditionnez les builds à l'absence des vulnérabilités dont vous avez décidé qu'elles ne doivent pas être livrées, pour qu'une correction ne puisse pas régresser discrètement.
  5. Refus par défaut du trafic sortant en CI. Ne laissez les builds atteindre que leurs sources de paquets et leurs cibles de publication, pour que du code malveillant ne puisse pas faire sortir de secrets, même lors d'une attaque que personne n'a encore vue.
  6. Isolez les jobs et limitez les secrets. Exécutez chaque job sur une machine neuve et isolée, et ne donnez à chaque job que les tokens et les permissions dont il a besoin.
  7. Vérifiez les artefacts avant de déployer. Signez la provenance au moment du build et vérifiez que ce qui s'exécute en production est exactement ce qui a été construit.
  8. Renouvelez les secrets après un incident. Si un paquet ou une Action compromis s'est exécuté dans votre pipeline, considérez chaque secret qu'il pouvait atteindre comme exposé. C'était le conseil de la CISA après la compromission de tj-actions.

Ils n'ont pas besoin de la liste. Vous, si.

Les attaquants surveillent chaque avis de sécurité et essaient l'exploit sur tout le monde le jour où une vulnérabilité est divulguée. Ils n'ont jamais eu besoin de votre liste de dépendances. Vous, si. CRACI donne à votre équipe cette liste, tirée du build lui-même, et ferme les portes sur lesquelles comptent les attaquants : le trafic sortant ouvert et les runners partagés.

Attaques de la chaîne d'approvisionnement : questions fréquentes

Qu'est-ce qu'une attaque de la chaîne d'approvisionnement logicielle ?

Une attaque visant le code, les outils ou les services à partir desquels un produit est construit, comme un paquet open source, un composant CI/CD ou le système de build, plutôt que le produit lui-même. Une seule compromission atteint toutes les organisations qui utilisent le composant concerné.

Quels exemples d'attaques de la chaîne d'approvisionnement logicielle peut-on citer ?

Le ver Shai-Hulud (depuis 2025) s'est propagé via des paquets npm infectés et a volé des secrets CI. La compromission de tj-actions/changed-files (CVE-2025-30066) a détourné une GitHub Action populaire. La porte dérobée de xz utils (CVE-2024-3094) a été glissée dans une bibliothèque de compression en amont. Log4Shell (CVE-2021-44228) a exploité une faille dans une bibliothèque de journalisation Java très répandue. Le Bash Uploader de Codecov (2021) a été modifié pour envoyer des identifiants CI à un serveur extérieur, et SolarWinds Orion (2020) a livré du code malveillant inséré au build.

Quelle est l'attaque de la chaîne d'approvisionnement la plus célèbre ?

SolarWinds. En 2020, des attaquants disposant d'un accès dissimulé au processus de build de SolarWinds Orion ont inséré du code malveillant dans ses releases, et les clients l'ont installé comme une mise à jour normale. Cette attaque a montré qu'un arbre source sain ne suffit pas : le build lui-même doit être digne de confiance et vérifiable.

Les attaquants savent-ils quelles dépendances mon entreprise utilise ?

Généralement non, et ils n'en ont pas besoin. La plupart des attaques visent un paquet plutôt qu'une entreprise : dès qu'un avis de sécurité est publié, les attaquants essaient l'exploit sur tout ce qui pourrait exécuter une version vulnérable et regardent ce qui répond. Des indices publics, comme les versions dans les bundles JavaScript ou les dépôts open source, les aident à viser. L'asymétrie, c'est que vous, vous avez besoin de la liste : pour savoir si vous êtes touché, vous devez savoir ce que chaque build a livré, y compris ce qu'il a récupéré en dehors du lockfile.

Comment prévenir les attaques de la chaîne d'approvisionnement logicielle ?

Aucun contrôle ne les arrête toutes à lui seul. Conservez une SBOM de ce que livre chaque build et surveillez-la par rapport aux nouveaux avis de sécurité, épinglez les dépendances et les GitHub Actions, bloquez les versions vulnérables au build, restreignez ce à quoi les jobs CI peuvent se connecter, isolez les jobs et limitez leurs secrets, et vérifiez que les artefacts déployés sont bien ceux que vous avez construits.

Comment me protéger contre les attaques de la chaîne d'approvisionnement npm ?

Commitez un lockfile et installez à partir de lui en CI, et désactivez les scripts d'installation là où un build n'en a pas besoin (--ignore-scripts de npm). Conservez un enregistrement des versions de paquets réellement installées par chaque build, afin de pouvoir vérifier rapidement lorsqu'une nouvelle vague telle que Shai-Hulud est annoncée. Restreignez ce à quoi les jobs CI peuvent se connecter, pour qu'un script d'installation malveillant ne puisse pas faire sortir vos tokens, et renouvelez tout token qu'une version infectée aurait pu atteindre.

Que signifie red team vs blue team ici ?

Dans les exercices de sécurité, la red team joue l'attaquant et la blue team défend. Cette page reprend ce partage : chaque étape d'une attaque de la chaîne d'approvisionnement avec les mots de l'attaquant, et la réponse de la défense.

CRACI détecte-t-il les paquets malveillants ?

Les paquets connus, oui. Une release malveillante qui a une CVE publiée, comme la porte dérobée de xz, est signalée comme n'importe quelle autre vulnérabilité, et une gate de politique peut bloquer les builds qui la contiennent. CRACI n'analyse pas le comportement des paquets et ne note pas leur réputation : un tout nouveau paquet malveillant n'est donc pas signalé tant qu'il n'existe pas d'avis de sécurité. C'est à cela que sert la politique de trafic sortant : avec le refus par défaut, le build ne peut atteindre que les hôtes dont il a besoin, et le paquet ne peut donc pas faire sortir vos secrets, même lors d'une attaque que personne n'a encore vue.