1 puntos por GN⁺ 2025-09-10 | 1 comentarios | Compartir por WhatsApp
  • El reciente ataque a la cadena de suministro en el ecosistema de paquetes de NPM en realidad pudo haber causado daños mucho mayores
  • El atacante usó código malicioso en bibliotecas populares únicamente para cambiar direcciones de billeteras de criptomonedas
  • El ataque se llevó a cabo mediante correos de phishing sofisticados para robar la información de autenticación de dos factores de desarrolladores
  • Si se hubiera usado de una forma más letal (por ejemplo, para robar claves de API), existía la posibilidad de daños masivos
  • Se enfatiza la idea de que todas las dependencias son potencialmente riesgosas y la importancia de comprender todo el árbol de dependencias

Resumen del ataque y preocupación

  • Recientemente, paquetes populares dentro de NPM, uno de los ecosistemas de paquetes más grandes, quedaron expuestos a un ataque
    • Ejemplos de funciones: manejo de colores en terminal, mapeo de nombres de colores a RGB, decoradores de depuración de funciones, utilidades para identificar valores similares a arreglos, etc.
  • Estas dependencias comunes se usan de forma muy amplia y, una vez que el código entra, hay muchas probabilidades de que se despliegue de inmediato en producción
  • Si hubiera incluido proxies maliciosos, robo de claves de API u otros ataques graves, existía el riesgo de consecuencias mucho más severas
  • En la práctica, ese malware solo alteraba direcciones de pago en criptomonedas dentro de billeteras en línea (por ejemplo, MetaMask)

La sofisticación del ataque de phishing

  • El punto de partida del ataque fue un correo de phishing muy bien elaborado
    • Usaba el nombre de usuario de NPM para dar una impresión personalizada
    • Generaba confianza con un mensaje que pedía "cambiar la contraseña y las credenciales de autenticación en dos pasos por seguridad"
    • Sumado a la forma particular en que opera NPM, el contenido estaba armado para que un usuario común pudiera caer fácilmente
    • Indicaba una fecha límite específica para crear urgencia e inducir a hacer clic en el enlace de phishing en un momento de descuido o prisa
    • Usaba un dominio .help similar al dominio oficial de NPM
  • La señal más visible era precisamente el uso de "npmjs.help" en lugar del dominio oficial
    • Hoy en día muchos gTLD (Generic Top Level Domain) nuevos se usan ampliamente en blogs y documentación, así que esto también puede parecer natural

El daño potencial del ataque

  • El correo de phishing permitía robar la información de autenticación de dos factores del usuario y luego publicar nuevos paquetes tras insertar código malicioso
  • Bibliotecas muy usadas como is-arrayish, color-string, color-name estuvieron entre los objetivos
    • Si el malware se hubiera expandido más allá del simple desvío de criptomonedas hacia algo como el robo de claves de API, podría haber provocado consecuencias devastadoras
    • Por ejemplo, una exposición masiva de claves API de OpenAI o AWS podría haber causado daños duraderos y a gran escala
  • En realidad, la mayoría de las bibliotecas infectadas se usan principalmente en herramientas de línea de comandos, por lo que el objetivo de robar criptomonedas era relativamente limitado

Objetivo en el ecosistema Web3 y estrategia del atacante

  • Este ataque parece haber tenido como objetivo principal a usuarios de Web3 (como quienes hacen pagos desde el navegador)
    • Al atacar bibliotecas de uso general no relacionadas directamente con Web3, evitó una detección y bloqueo rápidos dentro del ecosistema Web3
    • Por ejemplo, aunque se revise con atención una biblioteca integrada con Metamask, es difícil prever que el ataque ocurra en una utilidad relacionada con colores de texto

Lecciones para el ecosistema de desarrollo

  • Este caso subraya que cualquier paquete de dependencia puede ser realmente malicioso
    • Existen límites prácticos para controlar o monitorear por completo todo el árbol de dependencias en todo momento
    • También sugiere que, bajo flujos de despliegue rápido a producción y presión de tiempo, la revisión de seguridad puede quedar relegada
  • De ahora en adelante, cobra más importancia entender la composición completa de dependencias de un proyecto y gestionarla con cautela

Cierre y aviso

  • Este contenido no busca culpar ni responsabilizar a una persona específica; lo importante es reconocer que cualquiera puede quedar expuesto a un ataque de phishing
  • La situación puede haber cambiado desde la publicación de este post, así que si hay errores o dudas en el contenido, es necesario verificarlo directamente

Tags:

1 comentarios

 
GN⁺ 2025-09-10
Comentarios de Hacker News
  • El ataque a la cadena de suministro de nx en npm fue una bala que muchas empresas no habrían podido esquivar; con solo instalar el plugin de nx para VS Code, este verificaba automáticamente la versión más reciente de nx en npm, y si había credenciales importantes en la sesión de GitHub (por ejemplo, iniciando sesión en la cuenta corporativa con GH CLI) o en archivos .env, todo habría quedado expuesto. Esto era imposible de evitar incluso gestionando bien el version pinning de dependencias y las actualizaciones de seguridad. En este ecosistema se necesita un cambio mucho más profundo de raíz. Para más detalles, ver el aviso oficial de seguridad

    • Estoy evitando todo lo relacionado con NPM; la única excepción es el compilador de TypeScript, pero si lo reescriben en Go pienso quitar también eso. En Go destaca que se puede declarar una versión mínima y que nunca ejecuta lo descargado ni siquiera durante el proceso de compilación. En el caso de NPM, muchas veces el código difiere del de GitHub y me parece poco confiable.
    • Las extensiones de editor se actualizan e instalan automáticamente en entornos de desarrollo de alto riesgo, así que son un objetivo de ataque muy atractivo. Me sorprende que todavía no haya una compra masiva por parte de actores maliciosos como sí ocurrió con las extensiones de navegador. He oído que el equipo de VS Code invierte mucho esfuerzo en detectar malware, pero me pregunto si todos los editores, como Sublime, tienen procesos de validación así.
    • Yo mantengo todos los paquetes y bases de datos en local, y trabajo en modo avión en la máquina de desarrollo; solo conecto Internet al hacer git push.
  • De verdad nos salvamos por los pelos de una crisis gravísima. No puedo creer que un atacante con acceso a este tipo de paquetes se haya limitado a subir una sola herramienta para robar criptomonedas. Si fuera una oportunidad así de buena, parecería rentable invertir una semana más para implantar un exploit más sofisticado: hay demasiadas cosas que se pueden robar, como claves API, agregar claves públicas SSH, filtrar IPs de servidores, perfiles de navegador o tokens de sesión de dispositivos de desarrolladores, incluso la información de mi tarjeta de Amazon en el escritorio. Aunque no las usen directamente, todo eso se puede vender fácilmente en foros de la dark web. Me pregunto si los ciberdelincuentes más capaces ya trabajan en empresas tecnológicas estables y muy bien pagadas, y por eso solo quedan ataques tan simples.

    • Como era seguro que este método de ataque se descubriría rápido, no parece que hayan optado por algo sigiloso sino por tomar control total de las cuentas: entrar y salir rápido. Necesitaban una forma de sacar la mayor cantidad de dinero posible en pocas horas usando automatización, y las criptomonedas eran la respuesta obvia. Si el backdoor no iba a ser lo bastante bueno como para pasar inadvertido incluso si medio mundo revisaba el código, no había razón para prepararlo durante más tiempo.
    • Las criptomonedas robadas no se pueden revertir, reembolsar ni recuperar, así que en la práctica son un recurso que sí o sí se convierte en dinero. En cambio, las API o llaves SSH de un desarrollador casi no valen nada y, aun con suerte, para monetizarlas al final también se termina convirtiendo todo en criptomonedas.
    • Entrar rápido, robar cientos de miles de dólares, salir y repetir lo mismo meses después: si logran esquivar bien a la policía, pueden vivir sin preocupaciones toda la vida. Robar claves de AWS tampoco deja tanta ganancia. También hay criminales que buscan contraseñas o bases de datos de gestores de contraseñas en vez de criptomonedas, pero al final muchas veces terminan apuntando a sitios relacionados con cripto. Ahora mismo seguro hay delincuentes esperando el momento oportuno para infiltrar empresas con cuidado, y ellos se quedarán ocultos hasta tener éxito sin exponerse.
    • Esto no es una oportunidad única en la vida. A partir de ahora, los criminales se darán cuenta de que con apuntar apenas a unos cuantos “desarrolladores” ya pueden acceder fácilmente a millones de dólares, y seguirán apareciendo métodos cada vez más audaces. Si mantienes software open source, ya es nivel de ponerse a pensar seriamente qué tan bien estás ocultando tu identidad física en línea.
  • Mi hábito de posponer las cosas es una técnica de supervivencia. Espero a que otros hagan de beta testers, así que en una empresa usé Microsoft Office 2000 durante 12 años y tuve una década tranquila sin problemas por actualizaciones ni reentrenamiento. Y además tengo la costumbre de no hacer clic jamás en enlaces de correos.

    • Así ha sido también con mi Honda y con Kubernetes. Mantener por mucho tiempo un auto modelo 2006 me permitió saltarme varias generaciones de problemas grandes y pequeños de integración auto-teléfono, y apenas hace poco la conexión del iPhone en un auto modelo 2023 se volvió realmente fluida. Con Kubernetes fue igual: como fui aplazando durante mucho tiempo las recomendaciones de mi jefe, recién migré ahora que EKS, GKE y demás ya están lo bastante maduros, así que me ahorré mucho sufrimiento. Si le hubiera hecho caso de inmediato hace 6 o 7 años, creo que habría perdido incontables horas peleándome con eso.
    • En el ecosistema de npm, si no actualizas cada 54 segundos, ya te quedaste muy atrás.
    • Sirve contra paquetes maliciosos nuevos, pero no funciona si software ya infectado además recibe un worm.
    • Respondo mañana.
    • “Posponer por defecto 2 semanas el uso de una nueva versión” es una defensa muy efectiva contra ataques a la cadena de suministro.
  • Para una startup pequeña sería difícil, pero un actor grande como npm debería apartar todas las versiones TLD del dominio npm, como npm.io, npm.sh, npm.help, etc. Que el atacante se quedara con el dominio npm.help hizo que este ataque fuera todavía más efectivo.

    • Pasa mucho que, al mismo tiempo que te dicen que tengas cuidado con el phishing, empresas como AWS cambian la dirección oficial de facturación de no-reply-aws@amazon.com a no-reply@tax-and-invoicing.us-east-1.amazonaws.com. Como es una dirección que ves por primera vez, parece casi un correo de phishing, pero te dicen que es oficial y termina siendo confuso. Incluso el correo de aviso previo parece phishing, así que hasta recibir una factura real no abro el PDF adjunto por desconfianza. Las empresas les dicen a sus clientes que se cuiden del phishing mientras crean confusión innecesaria.
    • Hay más de 1,500 TLD, y aunque algunos sean restringidos o códigos de país, dan ganas de preguntarse cuánto costaría realmente al año registrar todos esos TLD. Seguro hasta debe haber servicios SaaS que lo hagan por ti.
    • Si ves la lista de TLD, hay demasiados dominios y, aunque incluso una empresa grande debería intentar apartar todos los TLD parecidos para prevenir phishing, no creo que eso pueda bloquearse por completo.
    • Lo primero es verificar si realmente se trata de un dominio oficial. Si es un dominio de descuento registrado recientemente o le queda poco tiempo antes de vencer, lo sospecho sí o sí. Sobre todo si el enlace intenta presionarte diciendo que no hay tiempo y resaltando fechas límite y cosas así; en esos casos investigo más a fondo. Creo que la comunicación oficial debería usar solo un dominio principal bien conocido, o sus subdominios.
    • En el caso de npm y dominios parecidos, las variantes no tienen fin, así que en la práctica es imposible frenarlo apropiándose de todos. Solo con ver el nombre ya puede parecer phishing, pero en la realidad hasta un dominio como npmjs.help puede recibir clics por error.
  • ¿Qué pasa si alguien combina una operación extremadamente meticulosa (al estilo Jia Tan) con lo floja que es nuestra seguridad (plugins de editor, shell userland, etc.)? Las herramientas para desarrolladores se ejecutan con privilegios de superusuario, pero son las menos auditadas. Yo tampoco puedo revisar una por una cosas como elisp, neovim, vscode o herramientas sencillas de userland; en el mejor de los casos, las tomo de nixpkgs. Bastaría con sacar un plugin mejor para VSCode y esperar 1 o 2 años. GG.

    • Ojalá algún día alguien resuelva de una vez el problema del xkcd 1200.
  • Aunque wallets como MetaMask fueron objetivo, he oído que MetaMask está bastante bien protegida contra ataques así gracias a un módulo de aislamiento llamado LavaMoat. De verdad me gustaría leer un análisis detallado sobre qué tan efectiva fue esa protección en la práctica. Personalmente no tengo relación con MetaMask, pero me da curiosidad la efectividad de este tipo de contramedidas de seguridad, que suelen implementarse más lento que los ataques reales. Dejo como referencia este artículo relacionado.

  • Ante la frase “la verdad es que con este tipo de phishing tarde o temprano te va a tocar”, yo personalmente creo que probablemente no. Tengo el hábito de no ingresar jamás credenciales en enlaces de correos que yo no haya solicitado directamente, como restablecimientos de contraseña y similares. Creo que es una habilidad de seguridad que todos deberían dominar en 2025.

    • Decir “'este tipo' de phishing” hace que suene como si hubiera sido un ataque sofisticado, pero en realidad fue otra vez un desarrollador cayendo en un correo de phishing totalmente común y corriente. Fue un error muy básico; a veces, ni el personal administrativo caería en algo así. Claro, cualquiera puede equivocarse, pero creo que este tipo de cosas se repite por descuido evidente y errores de aficionado.
  • A diferencia de lo que decía el artículo de que “todo el malware solo reemplazaba direcciones de wallets de criptomonedas”, la razón por la que MetaMask no se vio afectada fue:

  1. en el momento del ataque, el paquete no se actualizó de inmediato, y
  2. MetaMask estaba protegida usando LavaMoat tanto en la fase de instalación como en la de ejecución. En cambio, este payload malicioso intentaba apuntar a páginas web usadas con otras wallets que interactúan con MetaMask. Como referencia, participé en el desarrollo de LavaMoat. Para más información, ver el GitHub de LavaMoat
  • Los grandes repositorios públicos de paquetes necesitan soluciones de seguridad mucho más fuertes, o al menos debería existir un conjunto central de paquetes confiables y auditados. Lo mismo pasa en ecosistemas como Python y Rust, que también operan básicamente sobre la confianza.

    • El problema fundamental de npm es la falta de obligatoriedad de namespaces. En Maven de Java, los principiantes se quejan de “por qué no es tan fácil como npm”, pero con el tiempo valoro más y más la obsesión de Maven por el control de calidad, incluyendo su sistema de espacios de nombres. Aunque el POM xml sea incómodo, esa gestión conservadora del cambio transmite confianza. Artículo relacionado: Por qué los namespaces importan en los repositorios públicos de open source
    • Si, como en este caso, lo que se compromete es la cuenta misma del mantenedor del paquete, entonces medidas estructurales como los namespaces tampoco sirven de nada. La única solución es introducir una demora para que las nuevas versiones no se apliquen inmediatamente.
    • Las distribuciones de Linux también funcionan sobre la confianza, pero para conseguir permiso para subir paquetes hay que “demostrar” esa confianza, y existe todo un sistema de verificación. NPM se parece más a un sistema libre donde cualquiera puede subir cosas.
  • La afirmación de que “no hay forma de detener esto” solo aparece en los ecosistemas donde las intrusiones ocurren con mayor frecuencia.

    • Exactamente ese es el problema. Es una conclusión demasiado perezosa.