La cadena de suministro de software open source vuelve a ser el blanco de un ataque meticulosamente orquestado. Una campaña de malware en el ecosistema npm, centrada en el paquete malicioso ‘indexed-btree’, ha logrado acumular más de dos millones de descargas semanales burlando las defensas más recientes implementadas por GitHub y npm. El hallazgo, documentado por investigadores de Checkmarx, revela una evolución en las tácticas de los atacantes: en lugar de recurrir a scripts de instalación —ya bloqueados por las medidas de seguridad de npm v12—, el código malicioso se oculta en el comportamiento normal de ejecución de la librería, activándose únicamente cuando una aplicación invoca una función legítima con un valor específico.
Este movimiento no solo representa un paso adelante en la sofisticación de los ataques a la cadena de suministro, sino que expone una vulnerabilidad crítica en los modelos de detección actuales, que siguen centrados en analizar el momento de la instalación. La campaña, que ya habría generado beneficios significativos para los operadores —quienes controlan una billetera con 109 ETH, según el informe—, demuestra que la seguridad en el ecosistema npm requiere un enfoque que trascienda el escaneo estático y abrace el análisis dinámico en tiempo de ejecución.
La suplantación de una librería legítima: ‘sorted-btree’ como señuelo
El paquete ‘indexed-btree’ fue diseñado para hacerse pasar por la conocida y legítima librería ‘sorted-btree’, una estructura de datos de árbol B utilizada ampliamente en aplicaciones Node.js para indexación y ordenación. Esta estrategia de typosquatting —o suplantación por similitud de nombre— no es nueva, pero en este caso los atacantes fueron más allá: construyeron un repositorio en GitHub de apariencia completamente legítima, poblado con un historial de commits verosímil, y curaron una cuenta de desarrollador que reforzaba la ilusión de autenticidad.
El resultado fue un paquete que, a simple vista, parecía una alternativa confiable y bien mantenida. Los dos millones de descargas semanales que acumuló no fueron fruto del azar, sino de una campaña de distribución que logró infiltrarse en proyectos que, sin saberlo, incorporaron una puerta trasera silenciosa en su base de código.
¿Cómo evade el malware las medidas de seguridad de npm v12?
En junio de 2026, GitHub anunció un conjunto de medidas de seguridad para npm diseñadas específicamente para frenar los ataques a la cadena de suministro que venían sacudiendo el ecosistema desde finales de 2025. La más relevante de estas medidas es el bloqueo de los scripts de ciclo de vida de las dependencias —’preinstall’, ‘install’ y ‘postinstall’— a menos que el desarrollador los apruebe explícitamente. Además, npm dejó de recuperar automáticamente dependencias desde repositorios Git remotos o URLs externas sin permiso.
Estas protecciones cierran la puerta a los métodos clásicos de infección, donde el código malicioso se ejecutaba durante la instalación del paquete. Sin embargo, el paquete ‘indexed-btree’ las sortea por completo al no emplear ningún script de instalación. La instalación del paquete parece limpia; no activa ninguno de los mecanismos de aprobación de npm v12. El verdadero peligro yace en el código de la propia librería, específicamente en el método BTree.prototype.set(), la función principal que cualquier usuario de la librería llamaría constantemente para insertar o actualizar valores en el árbol.
El método set() contiene un loader oculto que se activa solo cuando la aplicación lo invoca con una clave (key) específica. Al alcanzar ese valor disparador, el loader ejecuta el archivo sharedLoad.min.js, que contiene la primera etapa del malware, ofuscada y diseñada para evadir tanto las herramientas de análisis de manchas (taint analysis) como la mayoría de los escáneres estáticos. La elección del método set() es particularmente astuta: es una operación que cualquier desarrollador que utilice un árbol B realizará de forma rutinaria, lo que garantiza que el malware se ejecute temprano en el ciclo de vida de la aplicación.
¿Qué ocurre una vez que el malware se activa?
Una vez que el método set() con la clave específica desencadena la ejecución de sharedLoad.min.js, el malware procede a recopilar información detallada del sistema infectado: arquitectura del procesador, nombre del host, CPU, memoria RAM y tiempo de actividad del sistema (uptime). Estos datos son exfiltrados a través de canales de Slack y Telegram cuyas credenciales están hardcodeadas en el código.
Pero la capacidad de comunicación del malware no termina ahí. El código también consulta un contrato inteligente de Ethereum en la red de prueba Sepolia (testnet) para obtener instrucciones del servidor de comando y control (C2). Para proteger esta comunicación, los atacantes implementan un intercambio de claves X25519, del cual derivan una clave AES que utilizan para descifrar una carga útil de segunda etapa almacenada en el propio contrato inteligente. Esto permite a los operadores actualizar el comportamiento del malware de forma remota y sigilosa.
Un detalle que subraya la profesionalización de la operación es la capacidad del malware para autodestruirse. Cuando los atacantes deciden finalizar el ataque, el código puede eliminar sus propios archivos y, más impresionante aún, borrar el trigger malicioso del método set() del paquete, dejando la librería limpia y sin rastro de la infección. Esta capacidad de borrado dificulta enormemente la atribución y el análisis forense posterior.
El alcance de la campaña: nueve paquetes adicionales vinculados
Los investigadores de Checkmarx no se detuvieron en ‘indexed-btree’. Durante su análisis, identificaron otros nueve paquetes en npm que forman parte de la misma operación, todos ya eliminados del registro. Las cifras de descargas acumuladas por estos paquetes revelan la magnitud del impacto:
- ordered-kv-index: 448.184 descargas
- btree-leaderboard: 493.685 descargas
- priority-slot-queue: 402.860 descargas
- btree-range-store: 468.092 descargas
- btree-core: 1.951.274 descargas
- btree-time-index: 425.312 descargas
- btree-lru-cache: 372.185 descargas
- neighbor-key-map: 366.019 descargas
- sliding-score-window: 448.024 descargas
Estos paquetes, que suman millones de descargas colectivas, siguen la misma estrategia: nombres que evocan funcionalidades legítimas de estructuras de datos y caching, repositorios falsamente activos y, presumiblemente, el mismo mecanismo de activación en tiempo de ejecución. La diversidad de nombres sugiere que los atacantes buscaban maximizar su superficie de ataque, infiltrándose en distintos tipos de proyectos.
Implicaciones para la seguridad de la cadena de suministro
Esta campaña representa un punto de inflexión en la comprensión de las amenazas a la cadena de suministro de software. Hasta ahora, la mayoría de las defensas se centraban en el momento de la instalación: escaneo de scripts, análisis de dependencias, verificación de integridad de los paquetes. Las medidas de npm v12 fueron un paso importante en esa dirección, pero el ataque con ‘indexed-btree’ demuestra que los actores de amenazas ya han encontrado una vía de evasión que explota un punto ciego fundamental: el comportamiento en tiempo de ejecución.
El hecho de que el malware se oculte dentro de una función que los desarrolladores invocan de forma legítima y constante plantea un desafío enorme para las herramientas de seguridad tradicionales. Los escáneres estáticos, que examinan el código sin ejecutarlo, tienen dificultades para detectar cargas útiles ofuscadas que solo se activan bajo condiciones específicas de entrada. Las herramientas de análisis de dependencias, que se ejecutan durante la instalación, no encuentran nada sospechoso porque no hay scripts que analizar. Es un ataque diseñado específicamente para pasar desapercibido bajo el radar de las defensas actuales.
¿Qué deben hacer los desarrolladores que instalaron estos paquetes?
La recomendación de los investigadores es clara y urgente: cualquier desarrollador que haya instalado ‘indexed-btree’ o cualquiera de los otros nueve paquetes listados debe rotar inmediatamente todos los secretos y credenciales que pudieran estar presentes en el entorno de desarrollo o en las máquinas infectadas. Además, es necesario restaurar el entorno de desarrollo a partir de una copia de seguridad limpia y anterior a la infección.
Pero más allá de la respuesta inmediata, este incidente subraya la necesidad de adoptar un enfoque de seguridad que incluya análisis de comportamiento en tiempo de ejecución. Herramientas que monitoreen las llamadas a funciones críticas, la comunicación con redes externas no autorizadas o la modificación inesperada de estructuras de datos podrían haber detectado la actividad anómala del método set() incluso sin conocer previamente la firma del malware. La comunidad de seguridad open source debe comenzar a integrar capacidades de detección dinámica en sus flujos de CI/CD, no solo como una capa adicional, sino como un componente esencial de la defensa contra este nuevo tipo de amenazas.
El factor económico: 109 ETH y la monetización del ataque
Uno de los aspectos más reveladores de la investigación es la posible motivación económica detrás de la campaña. Checkmarx identificó una billetera controlada por los atacantes que contiene 109 ETH, aunque el informe no especifica si esos fondos provienen directamente del robo de criptomonedas o de otras actividades ilícitas. Lo que sí está claro es que una operación de esta envergadura —con nueve paquetes adicionales, repositorios falsos meticulosamente construidos y un mecanismo de C2 basado en contratos inteligentes— requiere una inversión de tiempo y recursos considerable. Los 109 ETH, valuados en varios cientos de miles de dólares dependiendo de la cotización, sugieren que los atacantes esperaban —y posiblemente ya han obtenido— un retorno significativo.
La utilización de Ethereum y la red Sepolia para el C2 no es casual: los contratos inteligentes ofrecen un canal de comunicación persistente, inmutable y descentralizado, difícil de censurar o desactivar por las autoridades o los equipos de respuesta a incidentes. Es una táctica que ya se ha visto en ataques avanzados y que probablemente se replicará en el futuro.
Lecciones para el ecosistema npm y más allá
El caso de ‘indexed-btree’ debe servir como una llamada de atención para todo el ecosistema de desarrollo JavaScript. Mientras que las medidas de seguridad en la instalación son necesarias, no son suficientes. La confianza en un paquete open source no puede basarse únicamente en su apariencia externa —commits frecuentes, README bien redactado, estrellas en GitHub—, especialmente cuando los atacantes han demostrado que pueden falsificar todos esos indicadores.
Los mantenedores de paquetes y los equipos de seguridad de npm deberían considerar mecanismos adicionales como la verificación de firmas digitales en el código publicado, la auditoría obligatoria de cambios en funciones críticas (como el método set() de una librería de árbol B) y la implementación de sistemas de reputación basados en el comportamiento histórico real del paquete, no solo en métricas superficiales. Por su parte, los desarrolladores deben adoptar una postura de confianza cero incluso hacia las dependencias más aparentemente legítimas, monitoreando su comportamiento en tiempo de ejecución y cuestionando cualquier desviación inesperada.
La cadena de suministro de software es un ecosistema frágil donde la confianza es el pegamento que lo mantiene unido. Ataques como este erosionan esa confianza y demuestran que la seguridad no es un estado estático que se alcanza con una política o una herramienta, sino un proceso continuo de adaptación a unas amenazas que evolucionan al menos tan rápido como las defensas. Los dos millones de descargas de ‘indexed-btree’ son un recordatorio de que, en seguridad, el eslabón más débil no es la tecnología, sino nuestra propia capacidad de anticipar el próximo movimiento del adversario.