« Il n’existe aucun moyen de l’empêcher » : le seul gestionnaire de paquets où ce genre d’incident se produit régulièrement prend la parole
(kevinpatel.xyz)- Une attaque de la chaîne d’approvisionnement du registre npm a exposé des millions d’applications d’entreprise et des milliards d’enregistrements d’utilisateurs, mais l’écosystème l’accepte comme si c’était inévitable
- Le Senior Frontend Engineer Mark Vance épingle la réalité d’un monde où, même pour mettre une chaîne en majuscules, on dépend de 40 niveaux de dépendances imbriquées provenant de paquets non vérifiés
- La compromission d’un paquet utilitaire abandonné de longue date, injectant un crypto-miner dans des builds de production à l’échelle mondiale, est traitée comme une catastrophe naturelle
- L’écosystème Node.js considère l’exécution de code à distance malveillante comme une tragédie imprévisible, tandis que les équipes DevOps s’acharnent à faire tourner les clés AWS
- Les écosystèmes Go, Rust et les Web API natives servent de contrepoint, avec de solides bibliothèques standard et une vérification cryptographique qui réduisent la dépendance à des composants tiers
Satire d’une attaque de la chaîne d’approvisionnement npm
- Une attaque de la chaîne d’approvisionnement du registre npm a compromis des millions d’applications d’entreprise et exposé des milliards d’enregistrements d’utilisateurs, mais les développeurs de l’écosystème JavaScript la considèrent comme quelque chose qu’« on ne pouvait absolument pas éviter »
- Le Senior Frontend Engineer Mark Vance voit comme le prix du développement d’applications web modernes le fait de dépendre d’un arbre de 40 niveaux de dépendances imbriquées issues de paquets non vérifiés pour simplement mettre une chaîne unique en majuscules
- Le détournement d’un paquet utilitaire laissé à l’abandon, conduisant à l’injection d’un crypto-miner dans des builds de production partout dans le monde, est traité comme une catastrophe naturelle
- L’écosystème Node.js présente l’exécution de code à distance malveillante comme une tragédie imprévisible et adresse ses « pensées et prières » aux équipes DevOps occupées à remplacer les clés AWS
Le contraste entre npm et les autres écosystèmes
- Les écosystèmes Go, Rust et les Web API natives réduisent fortement la dépendance au code tiers grâce à de solides bibliothèques standard et intègrent une vérification cryptographique stricte dans leurs toolchains essentielles
- Le contraste est présenté de façon à dire que, dans ces écosystèmes, le nombre d’incidents où « le projet de week-end d’un étudiant décrocheur détruit une infrastructure logistique mondiale » était de 0 aujourd’hui
- Un porte-parole de npm affirme que, dans un monde où des acteurs malveillants existent, il faut simplement l’accepter, et qu’il n’existe ni politique de registre ni garde-fous de sandbox de build capables de l’empêcher
- Le registre npm est décrit comme un registre open source qui exécute par défaut des scripts d’installation arbitraires sur les machines locales, ce qui fait écho à la déclaration du porte-parole et au risque structurel
- La conclusion exprime sa compassion pour les victimes tout en disant qu’il faut rester résilient jusqu’à « la prochaine compromission inévitable demain matin »
1 commentaires
Commentaires sur Hacker News
Chacun aura son avis sur la période de cooldown, mais une bonne partie des récentes attaques sur la supply chain npm, dont axios et tanstack, auraient probablement pu être évitées avec un cooldown
Si vous utilisez Artifactory / Nexus, il y a de fortes chances qu’un cooldown soit déjà en place, et sinon c’est facile à configurer
La plupart des compromissions de npm ou PyPI ont été retirées en quelques heures, donc l’idée du cooldown est simplement « ignorer les paquets publiés depuis moins de N jours ». Même 1 jour aide, 3 jours c’est correct, et 7 jours est un peu excessif mais fonctionne
Pour le configurer, on peut soit utiliser une version récente de pnpm avec un cooldown par défaut d’un jour https://pnpm.io/supply-chain-security, soit, si l’on veut corriger ça d’un coup, utiliser https://depsguard.com qui ajoute un cooldown et des réglages recommandés à npm, pnpm, yarn, bun, uv et dependabot. J’en suis le mainteneur
Il y a aussi https://cooldowns.dev, davantage centré sur le cooldown, avec un script pour aider à la configuration locale. Tout est open source ou gratuit
Si vous savez déjà éditer vous-même
~/.npmrcet consorts, ce n’est sans doute pas nécessaire, mais pour les personnes autour de vous qui ont besoin d’une solution en un clic, cela peut les aider à éviter la prochaine attaqueEn revanche, s’il faut corriger un CVE critique récent, il faut contourner le cooldown, et chaque outil a sa manière de le faire. Je n’ai pas de chiffres précis, mais ces dernières semaines, le risque semble venir davantage des attaques sur la supply chain logicielle que des nouveaux CVE zero-day
Même chose pour les mises à niveau régulières de dépendances. Il existe bien des cas où il faut monter immédiatement de version, par exemple pour répondre à une vulnérabilité, mais dans ce cas je trouverais acceptable d’obliger le développeur à sélectionner explicitement la nouvelle version voulue
Si tout le monde met un cooldown de 7 jours, est-ce que ça n’explose pas simplement plus tard ?
En y repensant en écrivant, je suis quand même favorable à un cooldown de 10 jours consistant à ne rien installer de publié dans les 10 derniers jours. Je pense simplement qu’il ne faut pas s’attendre à ce que ce soit l’unique mesure d’atténuation
Je me demande ce que Go ou Rust garantissent réellement de plus que Python/npm. On dirait aussi que Python/npm sont simplement des cibles plus appétissantes
J’essaie de plus en plus d’éviter tous les paquets tiers
Maven Central existe depuis des décennies, et il y a eu très peu d’incidents de vol d’espace de noms
Impossible de publier un paquet avec le groupId
com.ycombinatorsans vérification de la propriété du domaine ycombinator.com. Et une fois publié, un paquet est 100 % immuable, même s’il contient du code malveillant. Bien sûr, une telle bibliothèque est ensuite signalée comme vulnérable un peu partoutJe ne comprends pas comment NPM n’a pas réussi, après tout ce temps, à reproduire des garde-fous comme ceux de Maven Central
Au lieu d’avoir un ensemble de bibliothèques validées distribuées avec le langage, les applications doivent soit les écrire elles-mêmes, soit les récupérer dans un dépôt tiers. Comme on a longtemps appris à éviter le NIH, les gens ont tendance à prendre un paquet
Ce n’est pas forcément mauvais en soi, mais cela attire souvent plus de code que nécessaire. L’écosystème JS privilégie aussi les petits modules, ce qui en multiplie le nombre, puis tout le monde réempile par-dessus, et le graphe de dépendances devient énorme. Volontairement ou non, la surface de problèmes potentiels est immense
Les autres langages offrent davantage de choses par défaut. Il y a bien eu des bugs et des problèmes de sécurité, mais c’est dérisoire comparé à ce qu’on voit dans l’écosystème JS. Le graphe de dépendances externes est bien plus petit et les fonctionnalités centrales viennent de tiers de confiance
Ce n’est pas une excuse pour NPM, au contraire, c’est juste un facteur de plus contre lui
On pourrait aussi dire que ces attaques montrent encore davantage la différence entre développeurs front-end et back-end, mais je n’irai pas jusque-là
Dans plusieurs entreprises, on s’est beaucoup battu pour installer une configuration npm globale sûre sur les machines de tous les développeurs, demander aux gens de ne pas la désactiver, et vérifier cela avec des outils MDM
Des paramètres par défaut plus sûrs auraient dû exister depuis longtemps
Il n’existe aucune raison légitime pour que les scripts postinstall existent. L’équipe npm devrait maintenant être assez mûre pour annoncer : « à partir de telle version de npm, les scripts postinstall ne seront exécutés que pour les versions de paquets publiées avant le ${today} »
C’est parce que des toolchains comme esbuild sont écrites dans des langages compilés et distribuées comme binaires via le dépôt npm. Si l’on utilise une version récente de Node/npm ainsi qu’un OS/une plateforme courants et récents, on devrait pouvoir désactiver tous les scripts postinstall sans problème légitime
Le code npm installé finit presque toujours par être exécuté
Mais le code ordinaire du paquet aussi. Même s’il n’est pas exécuté à l’installation, quelque chose dedans finira bien par l’être. Sinon, ce ne serait pas une dépendance au départ
Croire que supprimer les scripts postinstall aura autre chose qu’un effet momentané sur le taux d’exploitation montre qu’on n’a pas poussé la réflexion jusqu’au bout. Malheureusement, le problème est bien plus subtil que ne le laisse entendre l’article d’origine
Ce n’est pas une question du type « ne mettons pas le bouton qui fait tomber les ailes à côté de l’interrupteur », le cœur du problème est plutôt qu’il n’existe aucun moyen, sans travail manuel extrêmement pénible, de distinguer « le mauvais code de quelqu’un d’autre qui s’exécute sur ma machine » de « le bon code de quelqu’un d’autre qui s’exécute sur ma machine ». Et c’est précisément pour éviter ce travail pénible qu’on exécute le code d’autrui
Tous les projets Node.js commencent par
npm install, et soudain on se retrouve avec 500 paquets qu’on n’a jamais demandés. La moitié n’a pas été touchée depuis des annéesIl y a un problème culturel à vouloir mettre à jour vers les paquets les plus récents même quand ce qui existe déjà fonctionne très bien. Parfois les gens ne lisent même pas les notes de version pour voir si le changement les concerne
Le cooldown n’est qu’un moyen d’imposer un peu de patience aux mainteneurs, et en pratique cela aide
Un paquet Lisp peut rester utilisable 15 ans sans changement, alors qu’un paquet JS est traité comme un problème grave s’il n’a pas été maintenu. Même s’il était déjà terminé il y a 15 ans, on augmente quand même la version en n’ajoutant rien, ou parfois en introduisant des changements cassants, simplement pour avoir l’air géré sur npm et GitHub. Et ensuite tout le reste se met à jour
Un cooldown de 7 jours ressemble à un pansement facile à appliquer avec peu d’effort. La vraie solution serait probablement du build reproductible avec des attestations signées, mais la plupart des équipes ne paieront pas ce coût avant d’avoir déjà été frappées
On dirait un article de The Onion
Ce lien est une version manifestement blanchie par l’IA d’une blague que Xe Iaso traîne depuis longtemps. C’est dommage
https://xeiaso.net/shitposts/no-way-to-prevent-this/CVE-2024...
https://news.ycombinator.com/item?id=40438408
[0]: https://en.wikipedia.org/wiki/%27No_Way_to_Prevent_This,%27_...
https://en.wikipedia.org/wiki/%27No_Way_to_Prevent_This,%27_...