Attaques supply chain : comprendre, détecter et
s'en protéger
Attaque supply chain : ce que c'est, quatre cas réels et datés (event-stream, SolarWinds, xz-utils, polyfill.io), les vecteurs (dépendances npm, CI/CD, scripts tiers), et comment détecter la compromission côté surface externe.
own2pwn··16 min de lecture
Vous n'avez pas été piraté. Votre code est propre, vos serveurs sont à jour, votre mot de passe fait quarante caractères. Et pourtant, un matin, les portefeuilles Bitcoin de vos utilisateurs se vident. Le coupable n'est pas chez vous : c'est une brique open source, cinq niveaux plus bas dans votre arbre de dépendances, qu'un inconnu a récupérée puis piégée. Vous ne l'avez jamais installée volontairement. Elle est arrivée en passager clandestin, tirée par une autre bibliothèque que vous, si. Voilà une attaque supply chain : on ne vous vise pas, on vise ce que vous faites confiance.
Le terme est à la mode, mais l'idée est vieille comme le commerce : pour atteindre une forteresse bien gardée, on empoisonne ce qu'elle importe. Appliqué au logiciel, ça donne la compromission de la chaîne d'approvisionnement logicielle — un angle mort colossal, parce que le code moderne n'est plus écrit, il est assemblé. Un projet web banal embarque des centaines de dépendances qu'aucun humain n'a lues. Cet article fait le tour de la question : ce qu'est une supply chain attack, quatre cas réels et datés pour se faire une idée précise du danger, les vecteurs d'entrée, ce que valent le SBOM et la SCA, et surtout comment repérer une compromission depuis l'extérieur, là où vos utilisateurs la subissent.
Une attaque supply chain, c'est quoi exactement ?
Une attaque de la chaîne d'approvisionnement logicielle consiste à compromettre un maillon en amont — une dépendance, un outil de build, un fournisseur, un script hébergé ailleurs — pour atteindre, par ricochet, tous ceux qui l'utilisent en aval. L'attaquant ne force pas votre porte : il empoisonne quelque chose que vous allez inviter chez vous de votre plein gré, généralement lors d'un npm install, d'un pip install, d'une mise à jour automatique ou d'un <script src> pointant vers un CDN.
Le calcul de l'attaquant est purement économique : pourquoi attaquer mille entreprises une par une quand on peut compromettre une bibliothèque que ces mille entreprises importent ? Le rapport effort/portée est imbattable. C'est ce qui explique l'explosion de ces attaques : elles frappent en amont, à l'endroit où la confiance est implicite et la surveillance faible.
Le vocabulaire, vite fait
La confiance transitive, justement, est le cœur du problème. Vous faites confiance à la bibliothèque A. La bibliothèque A fait confiance à B. B tire C, qui tire D. Vous n'avez jamais entendu parler de D, son mainteneur est un pseudonyme, son dernier commit date de 2019 — et pourtant son code s'exécute avec les mêmes droits que le vôtre. Multipliez par les centaines de nœuds d'un node_modules typique, et vous obtenez une surface de confiance que personne ne maîtrise réellement.
Quatre attaques supply chain réelles, pour comprendre
Les définitions restent abstraites tant qu'on n'a pas vu le mécanisme à l'œuvre. Voici quatre cas documentés, choisis parce qu'ils illustrent chacun un vecteur différent : une dépendance npm, un pipeline de build, la confiance humaine dans un mainteneur, et un script tiers chargé dans le navigateur. Ce sont les quatre grandes portes d'entrée.
2018 — event-stream : la dépendance npm offerte puis piégée
event-stream était un paquet npm des plus anodins pour manipuler des flux de données, avec près de deux millions de téléchargements par semaine. Son auteur, Dominic Tarr (@dominictarr), ne s'en servait plus et l'avait laissé dormir. En septembre 2018, un contributeur au pseudonyme @right9ctrl propose gentiment de reprendre la maintenance. Tarr accepte et lui donne les clés — sur GitHub comme sur npm.
La suite est un cas d'école. Le nouveau mainteneur ajoute une dépendance, flatmap-stream, dont la version 0.1.1 embarque, uniquement dans sa version minifiée, du code malveillant chiffré. Ce code ne se déclenche que dans un contexte très précis : le processus de build de copay, un portefeuille Bitcoin qui comptait event-stream parmi ses dépendances. La charge utilise la description du paquet parent comme clé de déchiffrement AES : partout ailleurs, elle produit du charabia et se tait ; chez la cible, elle déchiffre un voleur de clés de portefeuille. Une attaque chirurgicale, invisible pour l'immense majorité des installations, découverte presque par hasard par un développeur intrigué par un avertissement de build.
La leçon event-stream
2020 — SolarWinds / SUNBURST : le pipeline de build empoisonné
Ici, on change d'échelle. SolarWinds édite Orion, une plateforme de supervision réseau déployée dans des dizaines de milliers d'organisations, dont des agences fédérales américaines. Des attaquants, attribués à un groupe étatique, ne piègent pas une dépendance : ils s'infiltrent dans l'environnement de build de SolarWinds lui-même. Le premier update Orion vérolé est signé le 24 mars 2020 et distribué à partir du 26 mars, à travers le canal de mise à jour officiel, dûment signé numériquement.
C'est là que réside le génie noir de l'attaque : la porte dérobée, baptisée SUNBURST, était intégrée à un binaire légitimement signé par SolarWinds. Aucune vérification de signature ne pouvait la détecter, puisqu'elle venait de la chaîne officielle. Jusqu'à 18 000 organisations ont téléchargé la mise à jour piégée ; une centaine, triées sur le volet, ont fait l'objet d'une intrusion approfondie. L'affaire n'a éclaté qu'en décembre 2020, quand l'éditeur de sécurité FireEye a découvert avoir été lui-même compromis par ce biais.
Pourquoi SolarWinds a marqué les esprits
2024 — xz-utils / CVE-2024-3094 : deux ans de patience pour une backdoor
Le cas xz-utils est le plus vertigineux, parce qu'il attaque la ressource la plus précieuse de l'open source : la confiance humaine. liblzma, la bibliothèque de compression fournie par xz-utils, est présente dans quasiment toutes les distributions Linux, et liée à des composants aussi sensibles que le démon SSH. Un contributeur signant « Jia Tan » (JiaT75) s'investit pendant près de deux ans dans le projet, gagne la confiance du mainteneur épuisé, obtient les droits de publication — puis glisse une porte dérobée dans les tarballs de release des versions 5.6.0 (février 2024) et 5.6.1.
La backdoor, dissimulée dans des fichiers de test binaires et reconstruite à la volée pendant le build, modifiait liblzma pour détourner l'authentification de sshd : quiconque possédait la bonne clé privée pouvait exécuter du code à distance, en root, sur des millions de machines. Score CVSS : 10.0, le maximum. Elle n'a été découverte que grâce à un développeur Microsoft, Andres Freund, intrigué par… quelques centaines de millisecondes de latence anormale sur des connexions SSH. Divulgation le 29 mars 2024, juste avant que les versions piégées n'atteignent les distributions stables. On est passé à un cheveu d'une catastrophe planétaire, sauvés par la curiosité d'un seul ingénieur.
2024 — polyfill.io : le script tiers qui trahit dans le navigateur
Les trois premiers cas frappaient au build ou au serveur. Celui-ci frappe dans le navigateur de vos visiteurs, et c'est pour ça qu'il nous intéresse particulièrement. polyfill.io était un service très répandu qui servait, depuis son CDN, de petits bouts de JavaScript pour faire fonctionner les sites modernes sur les vieux navigateurs. Plus de 100 000 sites chargeaient un <script> pointant vers cdn.polyfill.io.
En février 2024, le domaine et le dépôt GitHub passent sous le contrôle d'une société chinoise, Funnull. L'auteur original, Andrew Betts, exhorte publiquement tout le monde à retirer le script au plus vite. Il avait raison : le CDN se met à injecter du code malveillant, qui redirige les utilisateurs mobiles vers des sites d'arnaque et de paris, avec des techniques d'évasion soignées (il évite les administrateurs, se tait si un outil d'analyse est présent, ne se déclenche qu'à certaines heures sur certains appareils). L'éditeur Sansec sonne l'alerte le 25 juin 2024 ; le registrar Namecheap finit par neutraliser le domaine. Détail qui pique : la plupart des sites touchés n'avaient rien changé chez eux. Ils avaient juste laissé, des années plus tôt, une balise <script> vers un domaine tiers — et ce domaine a changé de camp.
La famille Magecart
Ce n'est ni ancien, ni terminé
chalk et debug (plus de 250 millions de téléchargements hebdomadaires chacun) ont été compromis via l'hameçonnage d'un mainteneur. Dans la foulée, le ver auto-répliquant « Shai-Hulud » a contaminé 500 paquets et plus en volant les jetons npm et GitHub pour se propager tout seul de mainteneur en mainteneur, avec une seconde vague fin novembre 2025. Le rythme des compromissions de dépendances npm ne fait que croître.Les vecteurs : par où entre une attaque supply chain
Nos quatre cas dessinent la carte. Une chaîne d'approvisionnement logicielle s'attaque à plusieurs étages, du code source que vous importez jusqu'au JavaScript qui s'exécute chez vos visiteurs. Voici les étages, du plus profond au plus visible.
Les dépendances open source. C'est le vecteur le plus courant, et de loin. Plusieurs techniques cohabitent : la prise de contrôle d'un paquet abandonné (event-stream), le vol du jeton de publication d'un mainteneur (par hameçonnage, comme chalk et debug), la publication d'une version malveillante par un mainteneur devenu hostile, et surtout le typosquatting — publier reqeusts ou loadash en pariant sur vos fautes de frappe. On a consacré un article entier à ce dernier : comment fonctionne le typosquatting de paquets et de domaines et comment le détecter.
La confusion de dépendances (dependency confusion). Une variante redoutable : si votre build cherche un paquet interne @masociete/utils et qu'un homonyme public du même nom existe sur npm avec un numéro de version plus élevé, votre gestionnaire de paquets peut aller chercher le public. L'attaquant n'a qu'à deviner le nom de vos paquets privés — souvent lisibles dans un vieux package.json qui a fuité — pour faire exécuter son code au cœur de votre CI.
Le pipeline CI/CD. Votre build system est votre joyau : il a accès au code, aux secrets, aux clés de signature, et son résultat est déployé partout, avec confiance. Le compromettre (via une action GitHub tierce non épinglée, un runner mal isolé, un secret exfiltré) revient à signer soi-même le malware, comme dans SolarWinds. Un cousin fréquent : le vibe coding et les dépendances hallucinées, un sujet qu'on creuse dans sécurité du code généré par IA.
Les scripts tiers côté navigateur. Le vecteur le plus sous-estimé, parce qu'il ne laisse aucune trace dans votre dépôt. Chaque <script src> vers un tag manager, un outil d'analytics, un chatbot, une régie publicitaire ou un CDN est une délégation de confiance à un tiers, qui s'exécute avec les pleins pouvoirs sur vos pages. Si ce tiers est compromis — ou racheté par un acteur hostile — c'est polyfill.io. Ce vecteur-là ne se voit pas depuis le code : il faut regarder ce qui se charge réellement dans le navigateur.
SBOM et SCA : la défense classique, et sa frontière
Face à cette prolifération, deux outils sont devenus la réponse standard. Ils sont indispensables — mais il faut comprendre où s'arrête leur portée.
Le SBOM (Software Bill of Materials, nomenclature logicielle) est l'inventaire exhaustif des composants qui entrent dans votre logiciel : chaque dépendance, sa version, sa licence, son origine. Les formats standards sont CycloneDX et SPDX. Un SBOM répond à une question simple mais vitale : « quand la prochaine faille type xz-utils tombe, suis-je concerné, et où ? ». Sans lui, vous passez des jours à fouiller vos projets à la main. Les réglementations récentes, NIS2 et DORA en tête, poussent d'ailleurs à formaliser cette gestion des risques liés aux fournisseurs — un point qu'on développe dans notre pilier sur la directive NIS2.
La SCA (Software Composition Analysis, analyse de composition logicielle) exploite ce SBOM : elle confronte votre liste de dépendances aux bases de vulnérabilités connues et vous alerte quand une version embarquée est concernée par une CVE. C'est le prolongement naturel du SBOM, et l'un des maillons d'une chaîne d'outils qu'on compare dans SAST, DAST et IAST. Notre propre module d' analyse de composition logicielle s'occupe des dépendances déclarées dans votre code.
Ce que le SBOM ne voit pas
<script> tiers chargé dynamiquement dans le navigateur de vos visiteurs, ni le CDN qui change de propriétaire après votre déploiement, ni le paquet dont la santé se dégrade six mois plus tard. La menace polyfill.io est par construction hors du champ d'un SBOM classique. C'est exactement le trou que la détection côté surface externe vient combler.Détecter la compromission depuis la surface d'attaque externe
Le SBOM regarde votre logiciel de l'intérieur, à la compilation. Mais une partie de votre chaîne d'approvisionnement ne vit qu'à l'exécution, dans le navigateur, et échappe donc à cette vue. Pour la couvrir, il faut adopter le point de vue de l'attaquant — et de l'utilisateur : regarder ce qui se charge réellement sur vos pages publiques, depuis l'extérieur. C'est le domaine de la gestion de la surface d'attaque externe (EASM), dont la sécurité de la chaîne d'approvisionnement est un volet à part entière.
Concrètement, on crawle vos pages avec un vrai navigateur, en passif (aucun payload, aucune exploitation, compatible production), et on inventorie chaque script tiers qui s'exécute vraiment : tag manager, analytics, widgets, chatbots, CDN, pixels marketing. Un fichier JavaScript minifié ne dit pas d'où il vient ; on remonte donc sa provenance — chemins node_modules résiduels dans le bundle, source maps exposées, en-têtes de licence — pour rattacher le code chargé aux paquets npm dont il est issu, et à leur version. On passe ainsi de « un blob de 400 ko » à une nomenclature réelle de ce qui tourne chez vos visiteurs.
Une fois la provenance établie, chaque dépendance est notée par risque : santé du paquet (abandon, bus-factor faible sur GitHub), signaux de paquet malveillant, dependency confusion, typosquat npm, intégrité de sous-ressource (SRI) manquante — l'absence de SRI étant précisément ce qui a rendu polyfill.io possible — ou secret oublié dans une source map exposée. Et parce qu'une surface d'attaque bouge tous les jours, la surveillance est continue : le jour où un CDN change de propriétaire ou qu'un nouveau script apparaît sur une page, l'alerte tombe. C'est ce que fait notre module sécurité de la chaîne d'approvisionnement.
Deux vues complémentaires, pas concurrentes
Réduire la surface : les réflexes qui paient
Aucune parade unique n'existe, mais quelques habitudes coupent la grande majorité des scénarios. Elles ne coûtent pas cher ; elles coûtent de la discipline.
- Épinglez tout. Versions exactes (lockfiles committés), hash des artefacts, actions CI épinglées par SHA et non par tag mouvant. Une version flottante
^0.1.0, c'est exactement la porte par laquelleflatmap-stream@0.1.1est entré. - Intégrité de sous-ressource pour tout script externe. Un attribut
integrity(SRI) sur vos balises<script>tierces bloque net toute modification du fichier servi. polyfill.io ne serait jamais passé avec du SRI en place. Mieux : self-hostez le JavaScript critique plutôt que de le tirer d'un CDN dont vous ne contrôlez pas le destin. - Réduisez la surface de dépendances. Chaque paquet ajouté est un mainteneur à qui vous accordez l'exécution de code. La dépendance la plus sûre est celle qu'on n'ajoute pas.
- Isolez le build. Runners éphémères, secrets à portée minimale, pas de token de publication qui traîne dans l'environnement d'un
preinstall. C'est ce genre de jeton que le ver Shai-Hulud a siphonné pour se propager. - Surveillez en continu, de l'extérieur. Un SBOM daté du mois dernier ne voit pas le CDN qui a basculé hier. La veille sur ce que vos pages chargent réellement est la seule à capter les compromissions qui surviennent après votre déploiement.
À retenir
L'essentiel sur les attaques supply chain
- Une attaque supply chain compromet un maillon en amont (une dépendance, un build, un script tiers) pour atteindre tous ceux qui lui font confiance. On ne vous vise pas : on vise ce que vous importez.
- Quatre cas, quatre vecteurs : event-stream (2018, prise de contrôle d'un paquet npm), SolarWinds (2020, pipeline de build signé), xz-utils (2024, backdoor par confiance humaine, CVSS 10), polyfill.io (2024, script tiers dans le navigateur). Et ça accélère (chalk/debug, ver Shai-Hulud en 2025).
- SBOM et SCA sont indispensables mais bornés : ils inventorient ce que vous déclarez et compilez, pas le JavaScript tiers chargé à l'exécution chez vos visiteurs.
- La détection côté surface externe comble ce trou : crawl passif au navigateur réel, attribution de provenance, notation par risque, surveillance continue — elle voit polyfill.io là où la SCA est aveugle.
- Réflexes qui paient : épingler les versions et les actions CI, poser du SRI (ou self-hoster) sur les scripts tiers, réduire les dépendances, isoler le build, et surveiller en continu depuis l'extérieur.
Le point aveugle, dans la plupart des organisations, ce n'est pas le code qu'on écrit : c'est le code qu'on charge, souvent sans le savoir, sur ses propres pages. Savoir précisément quels scripts et quelles dépendances tiers tournent chez vos visiteurs, d'où ils viennent et à quel point ils sont sains, c'est le métier de notre module sécurité de la chaîne d'approvisionnement, au sein de la plateforme EASM d'own2pwn. Ou parlez-en de vive voix avec un pentester via la page contact.
Articles liés
appsec
Ransomware (rançongiciel) : anatomie d'une attaque et comment protéger sa PME
Un ransomware chiffre vos fichiers et réclame une rançon. On décortique la chaîne d'attaque, on explique pourquoi les PME sont visées, et surtout comment se protéger d'un rançongiciel avant, pendant et après.
appsec
Gestion des vulnérabilités : le guide complet (cycle de vie, priorisation CVSS + EPSS + KEV)
Un scan crache 4 000 findings, 600 en « critique ». Par où commencer ? La gestion des vulnérabilités n'est pas un scan : c'est un cycle de vie et une priorisation. On démonte le processus, et pourquoi CVSS seul ne suffit plus (EPSS, KEV, exposition).
appsec
OSINT : le renseignement en source ouverte au service de la sécurité offensive
OSINT, définition, cycle du renseignement, sources et outils (Maltego, theHarvester, Amass, Shodan, SpiderFoot, recon-ng). Comment la reconnaissance passive cartographie une surface d'attaque avant la moindre requête intrusive, et pourquoi c'est le point de départ de tout pentest.