Aikido

npx Confusion : Des packages qui ont oublié de revendiquer leur propre nom

Charlie EriksenCharlie Eriksen
|
#
#
#

En juillet 2025, je prototypais un nouveau projet et j'ai décidé d'essayer MikroORM. La documentation indiquait d'exécuter npx mikro-orm-esm pour les migrations. Ce que j'ai fait.

npm ERR! code E404
npm ERR! 404 Non trouvé - GET https://registry.npmjs.org/mikro-orm-esm

Le paquet n'existe pas, c'est étrange ! Puis j'ai réalisé : et si quelqu'un l'avait enregistré ? J'aurais vu :

Les paquets suivants doivent être installés :
mikro-orm-esm@1.0.0
Continuer ? (o)

J'aurais simplement tapé o. Tout le monde le fait. Et rien dans cette invite ne vous indique si vous êtes sur le point d'installer un logiciel malveillant ou un outil légitime.

La documentation faisait référence à un paquet inexistant. Combien d'autres références à des paquets Phantom circulent ? Combien ont déjà été revendiquées par des attaquants ? Je devais le savoir.

J'ai donc commencé à creuser. J'ai écrit des scripts pour scanner npm à la recherche de paquets référencés dans READMEs et scripts mais jamais réellement publiés. J'ai recoupé des milliers d' npx invocations. J'en ai trouvé des dizaines. J'en ai revendiqué 14 avant que quiconque ne puisse le faire. Puis S1ngularity est arrivé, et la recherche a été mise de côté.

Six mois plus tard, ma recherche m'a été rappelée grâce à la communauté qui faisait des recherches similaires. J'ai finalement vérifié le nombre de téléchargements : 121 539 téléchargements !

Les gens avaient exécuté ces commandes inexistantes des milliers de fois par semaine. Pendant des mois. Pendant que les paquets restaient là à collecter des données. 

Six mois de données

Les téléchargements ne sont pas restés stables. Ils ont augmenté. Le démarrage a été lent fin juillet. Le pic récent a atteint 4 236 téléchargements en une seule journée (16 janvier 2026).

121 539 téléchargements sur 7 mois
128 paquets npx Phantom, de juillet 2025 à janvier 2026
121,539
Total des téléchargements
3,903
Moyenne hebdomadaire
4,236
Jour de pointe (16 janv.)
4K 3K 2K 1K 🎄 Creux des fêtes Pic : 4 236 Juil. Août Sept. Oct. Nov Déc Janv
Le volume de téléchargements hebdomadaires a augmenté régulièrement de juillet 2025 à janvier 2026
  • Total : 121 539 téléchargements pour 128 packages
  • Moyenne hebdomadaire : 3 903
  • Jour de pointe : 4 236 téléchargements (16 janv. 2026)

Petite remarque sur le bruit : chaque fois que vous publiez une nouvelle version d'un package, elle génère automatiquement 60 à 100 téléchargements provenant de scanners de sécurité et de miroirs. C'est le bruit de base par version. Les packages avec plusieurs versions accumulent rapidement ce bruit. Tout ce qui dépasse constamment ce seuil correspond à une utilisation réelle.

Remarquez la baisse fin décembre ? Ce sont les vacances. Même les téléchargements de packages Phantom prennent des congés à Noël.

Les Trois Grands

Trois packages représentent 79 % de tous les téléchargements :

  • openapi-generator-cli: 48 356 téléchargements (package réel : @openapitools/openapi-generator-cli)
  • cucumber-js: 32 110 téléchargements (package réel : @cucumber/cucumber)
  • depcruise: 15 637 téléchargements (package réel : dependency-cruiser)
Les Trois Grands : 79 % de tout le trafic
Trois packages Phantom représentent 96 103 des 121 539 téléchargements totaux.
openapi-generator-cli → réel : @openapitools/openapi-generator-cli
48,356
23 références npm650 résultats GitHub3 994 ces 7 derniers jours
cucumber-js → réel : @cucumber/cucumber
32,110
28 références npm856 résultats GitHub
depcruise → réel : dependency-cruiser
15,637
27 références npm836 résultats GitHub

openapi-generator-cli a enregistré 3 994 téléchargements au cours des 7 derniers jours seulement. C'est près de 4 000 fois que quelqu'un a tenté d'exécuter une commande inexistante. En une semaine.

La longue traîne

Les packages restants avec un nombre significatif de téléchargements :

  • jsdoc2md: 4 641 téléchargements
  • grpc_tools_node_protoc: 4 518 téléchargements
  • vue-demi-switch: 1 166 téléchargements
  • styleguidist: 805 téléchargements
  • mikro-orm-esm: 314 téléchargements
  • pvbase64: 142 téléchargements
  • cromwell: 106 téléchargements
La longue traîne
Packages restants avec un nombre de téléchargements notables (à l'exclusion des trois principaux)
jsdoc2md
4,641
grpc_tools_node_protoc
4,518
vue-demi-switch
1,166
styleguidist
805
mikro-orm-esm
314
pvbase64
142
cromwell
106
📊 Seuil de bruit : Chaque nouvelle version génère 60 à 100 téléchargements de scanners. Les packages totalisant moins de ~100 téléchargements (affichés en gris) sont probablement du bruit. Tout ce qui dépasse ce seuil représente de vraies machines, de vrais environnements, de vrais identifiants.
1K+ téléchargements100-1K téléchargementsAu seuil de bruit

Vous vous souvenez de cette base de 60 à 100 téléchargements par version ? Un package avec 3 versions pourrait générer 180 à 300 téléchargements de pur bruit. fathym avec 83 téléchargements au total est probablement du pur bruit. Mais mikro-orm-esm avec 314 ? Même en tenant compte de plusieurs versions, ce sont de véritables tentatives.

styleguidist avec 805 téléchargements signifie des centaines d'exécutions réelles. Il pourrait s'agir de CI/CD qui le sollicite à plusieurs reprises. Il pourrait s'agir de dizaines de développeurs différents. Dans tous les cas, c'est une utilisation réelle d'un package qui ne devrait pas exister.

Comment nous les avons trouvés

Nous gérons un miroir complet du registre npm chez Aikido. Nous avons analysé chaque package.json et README sur l'ensemble du registre. Nous avons extrait npx commandes. Nous avons recoupé ces informations avec ce qui est réellement enregistré. Nous avons également effectué des recherches dans le code de GitHub pour voir à quel point ces commandes Phantom apparaissent dans la nature, dans la documentation, les configurations CI, les scripts, partout où les développeurs pourraient y faire référence.

Trois points de données pour chaque package :

  • Références du registre : Combien de packages npm mentionnent cette commande dans leur package.json ou README
  • Résultats GitHub : Combien de fichiers de code ou de dépôts référencent cette commande sur GitHub
  • Téléchargements : Combien de fois des personnes ont réellement tenté de l'exécuter

Nous en avons revendiqué 14 en juillet 2025. Lorsque j'ai repris la recherche en janvier, nous avons étendu notre analyse et en avons trouvé beaucoup plus. À ce jour, nous avons revendiqué 128 packages au total.

Répartition complète des packages
Références npm, résultats de recherche de code GitHub et téléchargements pour tous les packages revendiqués
Références npmRésultats GitHubTéléchargements
🔴 Vecteurs d'attaque majeurs (plus de 10 000 téléchargements)
Package Références GitHub Téléchargements
openapi-generator-cli 23 650 48,356
cucumber-js 28 856 32,110
depcruise 27 836 15,637
🟡 Vecteurs d'attaque significatifs (1 000 à 10 000 téléchargements)
Package Références GitHub Téléchargements
jsdoc2md 92 155 4,641
grpc_tools_node_protoc 83 226 4,518
vue-demi-switch 70 80 1,166
Seuil de risque modéré + bruit
Package Références GitHub Téléchargements
styleguidist FORTE EXPOSITION 246 286 805
mikro-orm-esm DOCS SEULEMENT 0 80 314
pvbase64 18 70 142
cromwell 31 23 106
git-scripts-pre-push FAIBLE CONVERSION 126 133 93
fathym FAIBLE CONVERSION 119 9 83
aofl, flatjs-forge 42, 30 30, 2 99, 91
Observation clé : Un nombre élevé de références npm n'équivaut pas toujours à un nombre élevé de téléchargements. styleguidist compte 246 références mais 805 téléchargements, tandis que mikro-orm-esm a 0 référence mais 314 téléchargements provenant uniquement de la documentation.

Quelques schémas à noter :

Vecteurs d'attaque majeurs (plus de 10 000 téléchargements) : openapi-generator-cli, cucumber-js, et depcruise tous montrent une forte corrélation entre les références npm, les mentions GitHub et les téléchargements réels. Ceux-ci seraient dévastateurs entre les mains d'un attaquant.

Forte exposition, faible conversion : styleguidist compte 246 références npm et 286 résultats GitHub, mais seulement 805 téléchargements. git-scripts-pre-push compte 126 références mais seulement 93 téléchargements. La visibilité n'équivaut pas toujours à l'exécution.

Vecteurs basés uniquement sur la documentation : mikro-orm-esm n'a aucune référence de package npm mais 80 résultats GitHub et 314 téléchargements. Preuve que la documentation seule peut générer des centaines d'installations, même sans aucune référence dans l'écosystème npm.

Pourquoi c'est dangereux

L'attaque est simple.

Un attaquant enregistre le package. Ajoute un post-installation script qui exfiltre les variables d'environnement : jetons npm, identifiants cloud, clés API, tout ce qui traîne. Puis attend.

Au plus fort, cela représente potentiellement environ 4 000 machines compromises par semaine. Postes de travail de développeurs. Serveurs CI. Environnements de build. Beaucoup fonctionnent probablement avec des identifiants dans des variables d'environnement. Aucun phishing n'est nécessaire. Aucun compromis de la chaîne d'approvisionnement des packages existants. Il suffit de revendiquer le nom et d'attendre que npx vous amène les victimes.

Quand quelqu'un exécute la commande, il voit :

Besoin d'installer les packages suivants :
openapi-generator-cli@1.0.0
Continuer ? (o)

L'invite ne montre pas qui l'a publié. Ne montre pas quand. Ne montre pas si c'est ce que vous cherchez. Vous pourriez voir cette invite régulièrement pour des outils légitimes. La mémoire musculaire prend le dessus, car nous sommes humains. Vous tapez o, comme tout le monde le fait. C'est tout. C'est toute l'attaque.

Nous avons comblé 128 lacunes sur plusieurs cycles. Nous avons identifié les pires cas. Mais il y a une longue traîne de milliers.

Une note sur les protections de npm

npm dispose d'une protection contre le typosquatting. Lorsque nous avons tenté de revendiquer certains noms, npm les a rejetés en raison d'erreurs de similarité. Des noms comme rsbuild, vuedoc, napi, t-ci étaient tous trop proches de paquets existants. C'est une bonne chose. Cela signifie que npm bloque activement les tentatives de squatting évidentes.

Mais ces commandes Phantom ne sont pas des fautes de frappe. Ce sont des noms qui n'ont jamais été enregistrés à l'origine. La vérification de similarité de npm ne les détecte pas car il n'y a rien à quoi être « similaire ».

Ce qu'il faut faire

Utilisez npx --no-install

npx --no-install votre-commande

Cela force npx à n'utiliser que les binaires locaux. Pas de repli sur le registre. S'il n'est pas installé, il échoue. C'est ce que vous voulez.

Installez les outils CLI explicitement. Ne vous fiez pas à npx pour les récupérer :

{
  "devDependencies": {
    "@openapitools/openapi-generator-cli": "^2.7.0"
  }
}

Vérifiez avant d'exécuter. La documentation indique d'exécuter npx quelque chose ? Vérifiez d'abord que le paquet existe réellement. Vérifiez que c'est le bon. Surtout en CI/CD.

Revendiquez votre espace de noms. Si vous maintenez un outil CLI, enregistrez les alias et les fautes d'orthographe évidentes. Une assurance bon marché contre toute action malveillante d'autrui.

Comment savoir si vous êtes concerné

Si vous êtes un utilisateur Aikido, vérifiez votre flux central et filtrez les problèmes de logiciels malveillants. Toute vulnérabilité de paquet Phantom apparaîtra comme un problème critique 100/100 dans le flux. Aikido rescane vos dépôts chaque nuit, bien que nous recommandions de déclencher également un rescan complet.

Si vous n'êtes pas encore un utilisateur Aikido, créez un compte gratuit et connectez vos dépôts. Notre couverture propriétaire des logiciels malveillants est incluse dans le plan gratuit (aucune carte de crédit requise).

Pour une protection future, envisagez d'utiliser Aikido SafeChain (open source), un wrapper sécurisé pour npm, npx, yarn et pnpm. SafeChain s'intègre à vos workflows actuels, interceptant les commandes d'installation de paquets et vérifiant les paquets par rapport à Aikido Intel (notre renseignement sur les menaces open source) avant qu'ils n'atteignent votre machine. Arrêtez les menaces à la porte.

Les chiffres

121 539 téléchargements en sept mois. 3 903 par semaine en moyenne. Pic de 4 236 en une seule journée. 128 paquets revendiqués au total (14 en juillet, le reste en janvier).

L'écosystème npm compte des millions de paquets. Les développeurs exécutent des commandes npx des milliers de fois par jour. L'écart entre le « défaut pratique » et l'« exécution de code arbitraire » est un nom de paquet non revendiqué.

Abonnez-vous pour les actualités sur les menaces.

Sécurisez votre environnement dès maintenant.

Sécurisez votre code, votre cloud et votre environnement d’exécution dans un système centralisé unique.
Détectez et corrigez les vulnérabilités rapidement et automatiquement.

Aucune carte de crédit requise | Résultats en 32 secondes.