En julio de 2025, estaba prototipando un nuevo proyecto y decidí probar MikroORM. La documentación indicaba que ejecutara npx mikro-orm-esm para las migraciones. Y así lo hice.
npm ERR! code E404
npm ERR! 404 Not Found - GET https://registry.npmjs.org/mikro-orm-esmEl paquete no existe, ¡qué extraño! Entonces caí en la cuenta: ¿y si alguien hubiera registrado esto? Habría visto:
Necesita instalar los siguientes paquetes:
mikro-orm-esm@1.0.0
¿Desea continuar? (y)Simplemente habría pulsado y. Todo el mundo lo hace. Y nada en esa indicación te dice si estás a punto de instalar malware o una herramienta legítima.
La documentación apuntaba a un paquete inexistente. ¿Cuántas otras referencias a paquetes Phantom están circulando? ¿Cuántas han sido ya reclamadas por atacantes? Tenía que saberlo.
Así que empecé a investigar. Escribí scripts para escanear npm en busca de paquetes referenciados en READMEs y scripts pero nunca publicados. Crucé miles de npx invocaciones. Encontré docenas. Reclamé 14 de ellos antes de que nadie más pudiera. Luego ocurrió S1ngularity, y la investigación se archivó.
Seis meses después, recordé mi investigación gracias a la comunidad que investigaba cosas similares. Finalmente, comprobé el número de descargas: 121.539 descargas.
La gente había estado ejecutando estos comandos inexistentes miles de veces a la semana. Durante meses. Mientras los paquetes simplemente permanecían allí recopilando datos.
Seis Meses de Datos
Las descargas no se mantuvieron estables. Crecieron. Empezaron lentamente a finales de julio. El pico reciente alcanzó las 4.236 descargas en un solo día (16 de enero de 2026).
- Total: 121.539 descargas en 128 paquetes
- Media semanal: 3.903
- Día pico: 4.236 descargas (16 de enero de 2026)
Una aclaración sobre el ruido: cada vez que se publica una nueva versión de un paquete, este obtiene automáticamente entre 60 y 100 descargas de escáneres de seguridad y mirrors. Ese es el ruido de referencia por cada lanzamiento. Los paquetes con múltiples versiones acumulan ruido rápidamente. Cualquier cosa que supere consistentemente ese umbral es uso real.
¿Ha notado la caída a finales de diciembre? Son las vacaciones. Incluso las descargas de paquetes phantom se toman un descanso en Navidad.
Los tres grandes
Tres paquetes representan el 79% de todas las descargas:
openapi-generator-cli: 48.356 descargas (paquete real: @openapitools/openapi-generator-cli)cucumber-js: 32.110 descargas (paquete real:@cucumber/cucumber)depcruise: 15.637 descargas (paquete real:dependency-cruiser)
openapi-generator-cli registró 3.994 descargas solo en los últimos 7 días. Esto significa que casi 4.000 veces alguien intentó ejecutar un comando que no existe. En una semana.
La cola larga
Los paquetes restantes con descargas significativas:
jsdoc2md: 4.641 descargasgrpc_tools_node_protoc: 4.518 descargasvue-demi-switch: 1.166 descargasstyleguidist: 805 descargasmikro-orm-esm: 314 descargaspvbase64: 142 descargascromwell: 106 descargas
¿Recuerdas esa base de 60-100 descargas por versión? Un paquete con 3 versiones podría tener entre 180 y 300 descargas de puro ruido. fathym con 83 descargas en total es probablemente todo ruido. Pero mikro-orm-esm ¿con 314? Incluso teniendo en cuenta varias versiones, eso son intentos reales.
styleguidist con 805 descargas significa cientos de ejecuciones reales. Podría ser CI/CD accediendo a él repetidamente. Podrían ser docenas de desarrolladores diferentes. De cualquier manera, es un uso real de un paquete que no debería existir.
Cómo los encontramos
Gestionamos un mirror completo del registro npm en Aikido. Analizamos cada package.json y README en todo el registro. Extrajimos npx comandos. Los contrastamos con lo que está realmente registrado. También buscamos en la búsqueda de código de GitHub para ver cuán ampliamente aparecen estos comandos Phantom en la práctica, en la documentación, configuraciones de CI, scripts, en cualquier lugar donde los desarrolladores puedan referenciarlos.
Tres puntos de datos para cada paquete:
- Referencias del registro: Cuántos paquetes npm mencionan este comando en su package.json o README
- Resultados de GitHub: Cuántos archivos de código o repositorios referencian este comando en GitHub
- Descargas: Cuántas veces la gente realmente intentó ejecutarlo
Reclamamos 14 en julio de 2025. Cuando retomé la investigación en enero, ampliamos nuestro análisis y encontramos muchos más. En este momento, hemos reclamado un total de 128 paquetes.
Algunos patrones a destacar:
Principales vectores de ataque (más de 10K descargas): openapi-generator-cli, cucumber-js, y depcruise todos muestran una fuerte correlación entre las referencias npm, las menciones en GitHub y las descargas reales. Estos serían devastadores en manos de un atacante.
Alta exposición, baja conversión: styleguidist tiene 246 referencias npm y 286 resultados en GitHub, pero solo 805 descargas. git-scripts-pre-push tiene 126 referencias pero solo 93 descargas. La visibilidad no siempre equivale a la ejecución.
Vectores solo de documentación: mikro-orm-esm no tiene referencias de paquetes npm pero sí 80 resultados en GitHub y 314 descargas. Prueba de que la documentación por sí sola puede impulsar cientos de instalaciones, incluso sin ninguna referencia del ecosistema npm.
¿Por qué es esto peligroso?
El ataque es simple.
Un atacante registra el paquete. Añade un postinstall script que exfiltra variables de entorno: tokens de npm, credenciales de cloud, claves API, lo que encuentre. Luego espera.
En el pico, eso supone potencialmente unas 4.000 máquinas comprometidas por semana. Estaciones de trabajo de desarrolladores. Servidores CI. Entornos de compilación. Muchas posiblemente se ejecutan con credenciales en variables de entorno. No se necesita phishing. Sin compromiso de la cadena de suministro de paquetes existentes. Solo hay que reclamar el nombre y esperar a que npx le traiga las víctimas.
Cuando alguien ejecuta el comando, ve:
Es necesario instalar los siguientes paquetes:
openapi-generator-cli@1.0.0
¿Desea continuar? (y)El aviso no muestra quién lo publicó. No muestra cuándo. No muestra si es lo que busca. Es posible que vea este aviso regularmente para herramientas legítimas. La memoria muscular toma el control, porque somos humanos. Escribe y, como todo el mundo hace. Eso es todo. Ese es el ataque completo.
Cerramos 128 brechas en múltiples rondas. Hemos detectado los peores casos. Pero hay una larga cola de miles.
Una nota sobre las protecciones de npm
npm sí tiene protección contra el typosquatting. Cuando intentamos reclamar ciertos nombres, npm los rechazó con errores de similitud. Nombres como rsbuild, vuedoc, napi, t-ci eran demasiado parecidos a paquetes existentes. Eso es bueno. Significa que npm está bloqueando activamente los intentos obvios de squatting.
Pero estos comandos Phantom no son errores tipográficos. Son nombres que nunca se registraron en primer lugar. La comprobación de similitud de npm no los detecta porque no hay nada a lo que ser "similar".
Qué hacer
Utilice npx --no-install
npx --no-install your-commandEsto obliga a npx a usar solo binarios locales. Sin recurrir al registro. Si no está instalado, falla. Eso es lo deseable.
Instale las herramientas CLI explícitamente. No dependa de npx para obtenerlas:
{
"devDependencies": {
"@openapitools/openapi-generator-cli": "^2.7.0"
}
}
Verifique antes de ejecutar. La documentación indica que se ejecute npx ¿algo? Verifique primero que el paquete realmente existe. Verifique que sea el correcto. Especialmente en CI/CD.
Reclama tu namespace. Si mantienes una herramienta CLI, registra los alias obvios y los errores tipográficos. Es un seguro barato contra alguien que lo haga maliciosamente.
Cómo saber si estás afectado
Si eres usuario de Aikido, revisa tu feed central y filtra por problemas de malware. Cualquier vulnerabilidad de paquetes Phantom aparecerá como un problema crítico 100/100 en el feed. Aikido vuelve a escanear tus repositorios cada noche, aunque recomendamos activar también un reescaneo completo.
Si aún no eres usuario de Aikido, configura una cuenta gratuita y conecta tus repositorios. Nuestra cobertura de malware propietaria está incluida en el plan gratuito (no se requiere tarjeta de crédito).
Para protección futura, considera usar Aikido SafeChain (código abierto), un wrapper seguro para npm, npx, yarn y pnpm. SafeChain se integra en tus flujos de trabajo actuales, interceptando los comandos de instalación de paquetes y verificando los paquetes contra Aikido Intel (nuestra inteligencia de amenazas de código abierto) antes de que lleguen a tu máquina. Detén las amenazas en la puerta.
Las Cifras
121.539 descargas en siete meses. 3.903 por semana de media. Pico de 4.236 en un solo día. 128 paquetes reclamados en total (14 en julio, el resto en enero).
El ecosistema de npm tiene millones de paquetes. Los desarrolladores ejecutan comandos npx miles de veces al día. La brecha entre el "valor predeterminado conveniente" y la "ejecución de código arbitrario" es un nombre de paquete no reclamado.

