Découverte de paquets npm malveillants dans l’ensemble des Red Hat Cloud Services
(github.com/RedHatInsights)- Le problème est toujours ouvert et, au moment de la rédaction, aucun responsable, jalon, branche liée ou PR n’est indiqué
- Il a été enregistré comme un incident de sécurité après la découverte de versions malveillantes dans plusieurs publications npm du périmètre
@redhat-cloud-services/ - Sont fournis en référence l’analyse de StepSecurity ainsi que les résultats de recherche OSS Security Feed
- La liste mise à jour des éléments touchés inclut 32 paquets, dont
@redhat-cloud-services/chrome,frontend-components,rbac-client,typesetvulnerabilities-client - Dans le tableau, les versions compromises sont le plus souvent au nombre de 3 par paquet, tandis que
@redhat-cloud-services/vulnerabilities-clientne comprend que les versions2.1.9et2.1.11 - D’après l’ensemble du tableau, il est possible de comptabiliser 95 versions compromises, et le titre d’une PR externe mentionnée séparément renvoie lui aussi à
95 versions - La famille
@redhat-cloud-services/frontend-components-*ainsi que plusieurs paquets*-clientsont touchés ensemble, ce qui montre qu’il ne s’agit pas d’un paquet isolé mais d’un problème affectant les publications de tout le même scope - Dans les commentaires, à la question « What are these? », une réponse indique « all that module is pwned », ce qui montre qu’une compréhension partagée considère l’ensemble de la liste comme compromis
- DanielRuf a indiqué avoir ajouté cet incident à supply-chain-incidents
- L’activité GitHub montre un résumé de contenu faisant référence à cette issue ainsi qu’une PR liée à la détection, mais le texte ne présente encore ni diagnostic de Red Hat, ni mesures d’atténuation, ni suppression éventuelle, ni version corrigée
1 commentaires
Avis sur Hacker News
J’espère qu’il est acceptable de relancer le fil pour parler de la configuration de cooldown. Axios, tanstack, @redhat-cloud-services et plusieurs attaques récentes sur la supply chain npm auraient pu être évitées avec un cooldown
Si vous utilisez Artifactory/Nexus, il est probable que vous l’ayez déjà, et sinon c’est facile à configurer. La plupart des compromissions de npm ou PyPI ont été retirées en quelques heures, donc il suffit d’ignorer les paquets publiés depuis moins de N jours. Même 1 jour est efficace, 3 jours c’est correct, et 7 jours est un peu excessif mais fonctionne
Les versions récentes de pnpm intègrent par défaut un cooldown d’1 jour : https://pnpm.io/supply-chain-security
Si vous voulez quelque chose en un clic, vous pouvez utiliser https://depsguard.com . C’est un CLI qui ajoute des cooldowns et des configurations recommandées à npm, pnpm, yarn, bun, uv et dependabot, et j’en suis le mainteneur
Il y a aussi https://cooldowns.dev, davantage centré sur les cooldowns, avec des scripts pour aider à la configuration locale. Tout est open source/gratuit
Si vous savez modifier directement
~/.npmrcet autres, ce n’est pas vraiment nécessaire, mais si vous connaissez des gens autour de vous qui ont juste besoin d’une correction en un clic, cela peut les aider à éviter la prochaine attaqueCela dit, quand il faut corriger un nouveau CVE critique, il faut contourner le cooldown, et chaque outil a sa propre manière de le faire. Je n’ai pas de chiffres précis pour les derniers mois, mais même à l’ère des découvertes de vulnérabilités façon Mythos, le risque semble plus élevé du côté des attaques sur la supply chain logicielle comme la publication de versions malveillantes que du côté des nouveaux CVE zero-day
~/.npmrcet d’ajouter une ligne, le besoin d’une correction en un clic me semble concerner un groupe très restreintIl est tout à fait possible de dire : « les correctifs de sécurité ne doivent contenir que des correctifs de sécurité, sans embarquer d’autres fonctionnalités ». Cela facilite l’audit, aussi bien pour les chercheurs en sécurité que pour les outils
On pourrait appliquer un cooldown aux versions ordinaires, et supprimer ce cooldown ou le rendre beaucoup plus court pour les correctifs de sécurité
Des systèmes comme Debian, avec des serveurs très stables et la possibilité de configurer unattended upgrades pour n’appliquer que les correctifs de sécurité, sont de bons exemples à suivre. Ces nouvelles versions de paquets sont aussi plus faciles à auditer pour les chercheurs en sécurité
Dans ce genre de fil, il y a toujours beaucoup de commentaires qui font comme si ce type d’attaque n’existait que sur npm, ou qui ironisent comme si rien n’avait été fait, mais je ne trouve pas ça juste.
Beaucoup de commentaires mentionnent aussi de bonnes fonctionnalités introduites pour protéger les consommateurs de paquets, comme les delay lines et pnpm.
On parle moins des outils côté mainteneurs de paquets. MFA pour la publication : https://docs.npmjs.com/requiring-2fa-for-package-publishing-..., ainsi que les trusted publishers, disponibles depuis environ un an : https://docs.npmjs.com/trusted-publishers
Plus récemment, staged publishing, qui combine les avantages des deux, a aussi été lancé : https://docs.npmjs.com/staged-publishing
On peut désormais publier depuis la CI sans identifiants statiques, puis exiger qu’un mainteneur approuve avec MFA avant la publication effective dans le registre. Si on le souhaite, on peut aussi exiger des validations multiples ou un délai côté CI via les protections GitHub Actions Environments.
Il faut encourager la communauté à adopter ce genre de garde-fous pour la publication, sinon ce problème continuera.
Dans ce cas, les paquets malveillants auraient eux aussi reçu l’étoile verte et rassuré les utilisateurs avec un message du type « compilé et signé avec preuve de provenance ».
[1] https://lwn.net/Articles/1075742/
C’est excellent qu’un travail soit en cours pour les empêcher, mais ça continue quand même. C’est drôle au sens « ah, ça recommence ».
Vu de l’extérieur, le développement web dégage une énergie de Far West chaotique : mutabilité, typage dynamique, standards et frameworks qui changent sans cesse, déploiement continu, CDN, campagnes A/B en temps réel, énormément de dépendances, et des données utilisateurs sensibles dispersées sur plusieurs infrastructures.
Je ne dis pas que cette vision est exacte, ni que l’attitude du type « bien fait » soit juste, mais je comprends d’où elle vient.
En particulier, aucune des deux n’aurait empêché l’introduction de la porte dérobée xz-utils dans une publication de paquet. xz-utils reste la référence en matière de compromission amont sophistiquée.
Le problème ici n’est pas qu’il faudrait mieux authentifier un amont auquel on fait déjà confiance, mais qu’on ne peut pas faire de l’amont l’unique source de confiance pour la sécurité. L’amont est un groupe de hackers peu intéressés par une ingénierie de release robuste, et pas très bons en la matière.
Mais il existe aussi des gens qui savent faire ça. La solution dans le monde Linux, et ce qui nous a sauvés avec xz-utils, c’est l’existence d’une deuxième couche humaine qui relit, audite, empaquette et adapte l’amont produit par les hackers pour les utilisateurs.
Ces personnes ont un autre regard, d’autres exigences côté consommateurs et d’autres critères de qualité, et elles détectent des bugs et des intentions malveillantes que l’amont n’est pas prêt à repérer.
NPM, cargo, PyPI, etc. continuent de penser qu’ils peuvent contourner ce besoin de travail humain, mais ils ne le peuvent pas. Dans l’écosystème NPM en particulier, il y a beaucoup de développeurs web habitués à des releases très rapides, à des exigences de compatibilité souples et à une réutilisation extrême, ce qui explique pourquoi ce genre de chose semble arriver plus souvent avec les paquets node qu’avec Python ou Rust.
Dans notre entreprise, nous utilisons yarn 4, qui propose une option bloquant l’installation des packages npm pendant les premiers jours suivant leur publication. Il semble que la plupart de ces attaques soient détectées pendant cette période (1 à 3 jours)
https://gist.github.com/mcollina/b294a6c39ee700d24073c0e5a4e...
Le package axios a été compromis, et les identifiants de son auteur ont aussi été volés, ce qui a fait échouer à nouveau chaque tentative de correction : https://www.trendmicro.com/en_us/research/26/c/axios-npm-pac...
L’utilitaire xz a contenu une backdoor pendant 2 mois : https://gigazine.net/gsc_news/en/20240403-timeline-of-xz-ope...
Un étudiant-chercheur a récupéré la maintenance des packages Python ctx et PHPass, y a diffusé des modifications malveillantes, et il a fallu plus de 7 jours pour les détecter et les corriger : https://infosecwriteups.com/how-i-hacked-ctx-and-phpass-modu...
Kaspersky a découvert plusieurs packages PyPI exploités pendant plus d’un an : https://www.kaspersky.com/about/press-releases/kaspersky-unc...
Le package « LoftyLife » a été exploité pendant plusieurs mois : https://securelist.com/lofylife-malicious-npm-packages/10701...
Si la fenêtre d’attaque passe à 7 jours, toutes ces nouvelles attaques intégreront une bombe à retardement qui ne s’activera qu’au 8e jour
pnpmpropose aussi cette fonctionnalité, activée par défaut à partir dev11: https://pnpm.io/settings#minimumreleaseageJ’ai quelques suggestions. Un cooldown des dépendances de 1 à 2 jours semble très efficace sans nuire à la capacité de corriger des CVE
Tous les endroits où du code s’exécute, comme
npm installounpm test, devraient tourner dans un environnement sans privilèges. Dans GitHub Actions, il est relativement simple de séparer les jobs qui buildent/testent les artefacts et ceux qui s’occupent du déploiement, de la signature, etc. Si vous utilisez l’IA, il suffit d’ajouter une skill/un guide imposant ce schémaSi vous utilisez GitHub Actions, installer la dernière version de zizmor améliore fortement la posture de sécurité
La deuxième mesure empêche que cela reste « propagable comme un ver », ce qui réduit une grande partie du problème actuel. La première donne aux entreprises du temps pour réagir aux attaques. Certains fournisseurs de ce domaine méritent aussi d’être évalués
C’était drôle comme blague, juste après avoir dit qu’il fallait retarder les nouveaux packages
On fait tourner un proxy Maven en local, et tous les builds s’exécutent dans des conteneurs. Python, npm et Go n’utilisent que des registres publics, donc ces builds aussi tournent en conteneur, sans besoin de proxy de registre
C’est le même jour que l’annonce par Red Hat et IBM de Project Lightwell, destiné à aider à détecter et corriger les vulnérabilités de la supply chain
https://www.redhat.com/en/lightwell
J’ai vu cette tirade intéressante il y a quelques jours : https://github.com/uNetworking/uWebSockets.js/blob/master/mi...
L’idée selon laquelle la bonne approche serait de forker toutes les dépendances qu’on utilise, puis de passer en revue et fusionner l’amont quand c’est nécessaire, avant d’installer depuis son propre dépôt, n’est pas dénuée de sens. Cela dit, ça a l’air incroyablement fastidieux.
C’est utile pour réduire, voire éliminer, la dépendance envers des hébergeurs tiers de dépendances, faire entrer les dépendances dans ses propres outils de revue de code, et garantir à long terme des builds reproductibles.
Packj(https://github.com/ossillate-inc/packj) détecte les dépendances malveillantes sur PyPI/NPM/Ruby/PHP, etc., via une analyse comportementale. Il analyse le code de manière statique et dynamique pour repérer des indicateurs de compromission comme l’exécution de shell, l’usage de clés SSH, les communications réseau ou l’utilisation de decode+eval. Il vérifie aussi plusieurs propriétés de métadonnées pour trouver des acteurs malveillants, comme le typosquatting.
J’ai supprimé Node de mon laptop il y a environ une semaine, et ça m’a fait du bien
J’essaie de faire tout mon travail dans des conteneurs de développement ou d’autres bacs à sable afin de réduire le rayon d’impact même si je me fais exploiter par malchance. Un attaquant pourrait peut-être récupérer des tokens Claude, mais il ne pourra pas facilement s’échapper du conteneur pour fouiller mon répertoire personnel.
Les délais de sécurité et les listes blanches de scripts d’installation sont de bons compléments pour une sécurité en profondeur, surtout en CI. Mais au fond, je pense que c’est le modèle de permissions du système d’exploitation qui doit changer. Le fait de faire confiance par défaut à des logiciels tiers avec l’ensemble des droits utilisateur ne fonctionne plus.
Il faudrait sans doute mettre le lien vers l’annonce d’origine
https://www.stepsecurity.io/blog/multiple-redhat-cloud-servi...
J’ai maintenant pris l’habitude d’utiliser le flag
--before=2026-05-30quand j’installe des paquets. Ça force la sélection d’une version publiée avant la date indiquée, et je choisis généralement une date d’environ 5 jours plus tôt.https://docs.npmjs.com/cli/v11/using-npm/config#min-release-...
pnpmet je définis unminimumReleaseAgeassez largehttps://pnpm.io/settings#minimumreleaseage
Heureusement, c’est activé par défaut à partir de la v11.
min-release-age=5dans le.npmrcà la racine du projet.NPM est cassé dès la conception, et le syndrome NIH omniprésent dans la communauté empêche même des mesures simples
Comme on y accepte énormément de paquets externes au lieu de développer en interne, les projets npm ont tendance à avoir des arbres de dépendances gros et complexes. Les plaintes concernant des paquets comme https://www.npmjs.com/package/is-windows existent depuis longtemps : il est trop facile d’écrire soi-même le même code, alors que ces paquets créent des vulnérabilités potentielles et des problèmes de maintenance.
Mais évidemment, il n’est pas nécessaire de tout refaire : il suffit d’implémenter les fonctionnalités dont on a besoin.
En plus, quand on ne code qu’une seule fonctionnalité, il n’y a pas besoin de créer des abstractions ou des interfaces de fonctions supplémentaires. C’est donc moins coûteux, et probablement mieux intégré.
Une autre erreur consiste à penser qu’on va forcément introduire des bugs et des vulnérabilités. Avec de mauvais développeurs, peut-être. Mais on peut éviter toute une catégorie de vulnérabilités qui apparaissent aux frontières d’intégration entre deux bibliothèques qui n’ont pas été conçues pour s’emboîter exactement. Et ce cas se présente souvent.