Código invisible en tus dependencias: el ataque a la cadena de suministro que no puedes ver
Hay ataques que llegan con sirenas. Este no. Este llega disfrazado de un commit con un pequeño arreglo de documentación, un ajuste de versión, quizás algún refactor menor. Todo parece normal. Y es justo ahí donde está el problema.
En los primeros días de marzo de 2025, investigadores de la empresa Aikido Security detectaron 151 paquetes maliciosos subidos a GitHub en apenas una semana, entre el 3 y el 9 de marzo. No es la primera vez que pasa algo así. Los ataques a la cadena de suministro de software llevan siendo un dolor de cabeza desde hace casi una década. Pero este caso tiene algo diferente, algo que lo hace especialmente difícil de detectar: el código malicioso es literalmente invisible.
El truco del código que no se ve
Para entender qué hace especial este ataque, hay que saber primero cómo funcionan normalmente los ataques de supply-chain en el mundo del software. La mecánica habitual es relativamente sencilla: un atacante sube un paquete a un repositorio público con un nombre parecido al de una librería legítima muy usada. Un desarrollador despistado confunde los nombres, lo incluye en su proyecto y listo, el código malicioso entra en producción. A veces estos paquetes llegan a descargarse miles de veces antes de que alguien se dé cuenta.
Lo que Aikido ha documentado ahora va un paso más allá. Los paquetes detectados usan una técnica que, hasta hace poco, prácticamente no se había visto en este contexto: caracteres Unicode invisibles para ocultar el código malicioso.
Qué es Unicode y por qué importa aquí
Unicode es el estándar que permite a los ordenadores representar texto de prácticamente cualquier idioma y sistema de escritura del mundo. Dentro de ese estándar existen zonas reservadas llamadas Public Use Areas (a veces denominadas Private Use Areas), pensadas originalmente para definir caracteres especiales, emojis, banderas o símbolos de uso privado.
El detalle técnico importante es este: algunos de esos puntos de código Unicode representan cada letra del alfabeto inglés, pero su representación visual es completamente invisible. Para el ojo humano, esa parte del código parece una línea en blanco o un espacio vacío. Para un intérprete de JavaScript, en cambio, es código ejecutable perfectamente válido.
Así que cuando un desarrollador revisa el paquete, cuando una herramienta de análisis estático lo escanea, o cuando una revisión de código se hace en cualquier editor o terminal convencional, no ve absolutamente nada sospechoso. El código malicioso no está oculto detrás de ofuscación compleja ni de cifrado elaborado. Está justo ahí, a plena vista, pero invisible.
Cómo funciona en la práctica
En uno de los paquetes analizados por Aikido, el ataque se materializa así: dentro del código aparece una cadena de texto entre acentos graves que, al inspeccionarla en cualquier visor, parece completamente vacía. Pero no lo está. Está cargada de caracteres Unicode invisibles que, durante la ejecución del código JavaScript, un pequeño decodificador extrae y pasa directamente a la función eval().
eval() en JavaScript ejecuta código arbitrario. Es, en términos de seguridad, una de las funciones más peligrosas del lenguaje. Y aquí se usa exactamente para eso: ejecutar un payload malicioso que en investigaciones anteriores del mismo grupo incluía scripts de segunda fase capaces de robar tokens, credenciales y secretos, usando incluso la blockchain de Solana como canal de entrega.
El resultado es que los escáneres no ven nada, los revisores no ven nada, y sin embargo el código se ejecuta con total normalidad.
El grupo detrás del ataque y el papel de la IA
Aikido ha bautizado al grupo responsable como Glassworm. La firma de seguridad Koi, que también ha estado siguiendo la misma campaña de forma independiente, llega a conclusiones similares.
Ambas empresas sospechan que Glassworm está usando modelos de lenguaje (LLMs) para generar los paquetes maliciosos. Y la razón es bastante lógica: producir 151 paquetes de alta calidad, cada uno adaptado al estilo y convenciones del proyecto que imita, con documentación coherente, versiones incrementales realistas y cambios de código que parecen legítimos, es algo que un equipo humano pequeño no podría hacer a esa escala y velocidad de forma manual.
Como señalan los propios investigadores: «Las inyecciones maliciosas no llegan en commits obviamente sospechosos. Los cambios que las rodean son realistas: ajustes de documentación, incrementos de versión, pequeños refactores y correcciones de bugs que son estilísticamente consistentes con cada proyecto objetivo.»
Esto es importante porque cambia el modelo de amenaza. Durante años, parte de la defensa ante este tipo de ataques ha pasado por identificar señales de baja calidad: código mal escrito, nombres de paquetes con errores tipográficos, descripciones genéricas o inconsistentes. Si la IA está generando estos paquetes, esas señales desaparecen o se reducen drásticamente. Y eso complica mucho las cosas.
Una técnica que ya había aparecido antes
Los caracteres Unicode invisibles no son nuevos. Existen desde hace décadas, aunque habían caído prácticamente en el olvido. Reaparecieron en el radar de seguridad en 2024, cuando se empezaron a usar para inyectar instrucciones maliciosas ocultas en prompts enviados a motores de inteligencia artificial. El texto era invisible para humanos y para escáneres de texto convencionales, pero los LLMs lo leían sin problema y seguían las instrucciones que contenía.
Los motores de IA han ido implementando medidas para restringir el uso de estos caracteres, pero esas defensas se han saltado de forma periódica. Y ahora la misma técnica ha migrado al malware más tradicional, con resultados preocupantes.
Por qué esto afecta a la ciberseguridad del software moderno
El ecosistema de desarrollo actual funciona sobre una cadena de dependencias extraordinariamente compleja. Una aplicación media puede tirar de decenas o cientos de paquetes externos, cada uno con sus propias dependencias. Nadie revisa manualmente todo ese código. No es humanamente posible. Por eso existen herramientas automáticas de análisis, escáneres de vulnerabilidades y pipelines de integración continua con controles de seguridad.
El problema de este ataque es que apunta directamente a esas herramientas. Si el código malicioso es invisible para los revisores humanos y para los escáneres estáticos, las capas de defensa más habituales dejan de funcionar. Y la calidad del código visible hace que los controles basados en reputación o en análisis de comportamiento superficial tampoco levanten alarmas.
Además, los 151 paquetes detectados probablemente sean solo una fracción del total. Muchos ya habían sido eliminados cuando los investigadores los encontraron, lo que sugiere que la campaña lleva más tiempo activa y tiene mayor alcance del que los datos actuales reflejan. Más allá de GitHub, repositorios como npm y el marketplace de VS Code también han sido afectados.
Qué se puede hacer
No hay una solución perfecta para esto, hay que ser honesto. Pero sí hay medidas concretas que reducen el riesgo de forma significativa:
- Auditar paquetes antes de incorporarlos, incluyendo un análisis hexadecimal o de puntos de código Unicode cuando algo no cuadra, especialmente si hay líneas que parecen vacías pero el fichero tiene un tamaño mayor del esperado.
- Revisar las dependencias de las dependencias, no solo el primer nivel. La mayoría de los ataques de cadena de suministro entran por dependencias transitivas, no directas.
- Usar herramientas que detecten caracteres Unicode inusuales, algo que los escáneres convencionales no hacen por defecto pero que puede configurarse o añadirse como paso adicional en el pipeline.
- Fijar versiones específicas de los paquetes y verificar hashes criptográficos cuando sea posible, para evitar que una actualización maliciosa se cuele de forma silenciosa.
- Aplicar el principio de mínima dependencia: si no necesitas un paquete externo para algo que puedes implementar en 10 líneas, no lo uses.
Ninguna de estas medidas elimina el riesgo por completo. Pero combinadas, elevan mucho el listón para un atacante, incluso uno que use IA para generar código de aspecto legítimo.
Una reflexión sobre hacia dónde va esto
Lo que documenta Aikido no es solo un ataque concreto. Es una señal de tendencia. La combinación de IA para generar código malicioso convincente y técnicas de evasión visual como los caracteres Unicode invisibles representa una evolución real en la sofisticación de los ataques a la cadena de suministro.
Durante años, el sector de la seguridad ha apostado por la automatización como respuesta a la escala de las amenazas. Más escáneres, más análisis automático, más detección basada en patrones. Este tipo de ataque sugiere que cuando los atacantes también tienen acceso a herramientas de automatización avanzadas y usan técnicas diseñadas específicamente para eludir el análisis automático, esa estrategia necesita revisarse.
No digo que la automatización no sirva. Sirve, y mucho. Pero hay que ser consciente de que no es suficiente por sí sola, especialmente cuando lo que tienes enfrente es código que, literalmente, no puedes ver.


