TanStack y MUCHOS paquetes más afectados: análisis profundo
MMaximilian Schwarzmüller
컴퓨터/소프트웨어경제 뉴스AI/미래기술
Transcript
00:00:00Tenemos otro gran, realmente gran ataque a la cadena de suministro ahora mismo y sigue en curso
00:00:06y se extendió de NPM también al ecosistema de Python, así que tal vez ahora mismo no instales ningún
00:00:12paquete de NPM o Python. Y asegúrate de que tu sistema esté configurado de forma segura en general. Tengo otro video
00:00:19sobre eso, compartiré un enlace abajo y volveré a ello aquí en este video también, pero primero quiero
00:00:23darte algunos detalles sobre qué está afectado y cómo saber si tú lo estás. Todo empezó con los
00:00:30paquetes de TanStack: TanStack query, TanStack router, TanStack start y demás. Ayer, 11 de mayo,
00:00:36en un lapso de tiempo bastante corto, un par de paquetes maliciosos o, de hecho, todos los paquetes de TanStack fueron
00:00:43publicados con versiones maliciosas y se contuvo rápidamente en 20 minutos. Al final
00:00:50se detectó y contuvo rápido, pero todos estos paquetes maliciosos se publicaron en ese
00:00:57lapso de tiempo o en ese corto periodo de tiempo aquí. Y luego continuó propagándose y todavía se está
00:01:03propagando. Llegó a los paquetes de Mistral que, jaja, solo tienen cuatro usuarios, pero aun así se vieron
00:01:09afectados porque este malware actúa como un gusano y roba datos, roba credenciales, también potencialmente
00:01:16las tuyas si está instalado en tu sistema. Volveré a cómo saber si estás afectado en solo
00:01:20un segundo, pero continuó extendiéndose a más paquetes de NPM porque esa es la idea detrás de esto y
00:01:26luego incluso al ecosistema de Python y eso está pasando justo ahora. Esto tiene apenas unas horas,
00:01:32dos horas en el momento en que estoy grabando esto. Ahora, ¿cómo saber si estás
00:01:39afectado? Si instalaste algún paquete de TanStack ayer por la tarde, en mi caso aquí en la zona horaria
00:01:45de Alemania, debes considerarte afectado. Si lo instalaste alrededor de esa hora, ten en cuenta
00:01:54que es UTC, así que tienes que traducirlo a tu zona horaria; en ese caso, debes considerarte
00:02:00afectado. Pero como se está extendiendo a los paquetes de Mistral, a muchos más paquetes de JavaScript,
00:02:06más de los que podría enumerar aquí, también debes considerar que tú o tu máquina están afectados y comprometidos.
00:02:13Y compartiré enlaces a estas publicaciones abajo para que puedas profundizar y ver la lista completa
00:02:18de todos estos paquetes afectados según se han publicado. Pero como mencioné, todavía está en curso,
00:02:22así que quizás no instales nada por ahora. También hay indicadores de compromiso. Debes
00:02:31buscar ciertos hashes de archivos, hashes SHA, para el router en un archivo JS. También enlazaré este post abajo.
00:02:38Y si tienes una forma de monitorear qué solicitudes de red ocurrieron en tu máquina,
00:02:42debes buscar tráfico saliente hacia esta URL, lo cual sería otro indicador claro
00:02:48de que se han exfiltrado datos de tu sistema. ¿Qué significa estar comprometido en detalle? Significa que
00:02:55este malware hace principalmente dos cosas. La primera cosa importante que hace es cosechar datos. Busca
00:03:03tokens de NPM, tokens de GitHub, credenciales de AWS, otros secretos. Escanea tu sistema buscando
00:03:12ubicaciones típicas donde guardas credenciales y secretos, los recopila y los envía a
00:03:18esta URL que te mostré. Así que roba estos secretos. Pero no solo hace eso. Como mencioné,
00:03:26actúa como un gusano, así que también usa estos tokens de GitHub robados. Por ejemplo,
00:03:33los usa junto con los tokens de NPM para publicar más paquetes comprometidos. Si eres el mantenedor
00:03:40de otro paquete, o si tal vez tienes un flujo de trabajo CI/CD que se ejecutó en ese tiempo y que
00:03:46dependía de algunos paquetes de TanStack, entonces en ese flujo CI/CD se han
00:03:53extraído los paquetes de TanStack comprometidos. El código malicioso pudo haberse ejecutado allí. Y luego en ese
00:04:00flujo de trabajo, no en tu máquina, sino en ese flujo, también podría robar ciertas credenciales
00:04:06para publicar una versión maliciosa, una versión comprometida del paquete que tu flujo CI/CD
00:04:14estaba tratando de construir. Así es como se propaga. Como mencioné, actúa como un gusano. Está usando estas
00:04:20credenciales y tokens robados para publicar más paquetes comprometidos. Y así es como llega
00:04:26a Mistral y luego también a otros paquetes de JavaScript, e incluso al ecosistema de Python. Y aquí
00:04:32es donde estamos ahora. Y por lo que sé, sigue extendiéndose. Ahora, ¿cómo puedes protegerte
00:04:39de eso? Creé un video sobre eso en mi otro canal, AkataMind. También lo enlazaré abajo.
00:04:44En resumen, quieres asegurarte de ejecutar tu código o hacer tu desarrollo,
00:04:51no directamente en tu máquina raíz si es posible, sino en alguna máquina virtual, en un dev container,
00:04:57algo así. No quieres almacenar secretos en crudo en tu máquina. Me refiero a que para AWS,
00:05:03por ejemplo, deberías usar su enfoque de inicio de sesión único en lugar de guardar credenciales IAM en
00:05:10tu máquina, por ejemplo, y usar técnicas similares para otros servicios que utilices. Además,
00:05:16también deberías considerar usar servicios como Infisical o Doppler para guardar tus secretos
00:05:25en la nube y no en tu disco duro, ni en archivos .env. Eso es algo que podrías querer hacer.
00:05:30Y de nuevo, hablo de esas cosas en ese video. Y también deberías usar gestores de paquetes
00:05:38y configuraciones que permitan configurar cosas como la edad mínima de lanzamiento, como permite Bun.
00:05:44En el archivo bunfig.toml, puedes establecer una edad mínima de lanzamiento, lo que asegura que incluso si
00:05:49ejecutas bun install, solo instales paquetes que tengan al menos X segundos o X días de antigüedad en este
00:05:56ejemplo. Ahora, pnpm tiene una función similar. Las versiones más recientes de npm tienen algo parecido.
00:06:02De nuevo, cubrí eso en ese otro video. Y si usas algo como Bun o si tienes
00:06:09la configuración correcta para npm, pero Bun lo hace por defecto, por ejemplo, también bloquea la
00:06:15ejecución de, por ejemplo, scripts post-instalación, o sea, scripts del ciclo de vida de los paquetes que
00:06:21estás instalando, lo cual te da otro mecanismo de seguridad porque ese malware típicamente depende
00:06:28de que tales scripts se ejecuten en tu sistema. Así que usar un gestor de paquetes seguro y/o una
00:06:36configuración segura para el mismo, ejecutar tu código en una máquina virtual o en un dev container
00:06:41y no guardar secretos en texto plano en tu sistema. Eso es lo que quieres hacer en general, pero ahora
00:06:46más aún porque estos ataques, ataques como estos aquí, se volverán más serios y profundizaremos
00:06:52en cómo funcionó este ataque porque es muy interesante. Pero por supuesto, estamos teniendo más de
00:06:58estos. Creo un video así casi cada mes ahora o incluso más seguido porque, para empezar,
00:07:04creo que son más fáciles de realizar. Ahora, en la era de la IA, es más fácil analizar los paquetes o
00:07:12las dependencias que quieres afectar y analizar su código fuente o su configuración CICD para posibles
00:07:22vectores de ataque. Eso es lo que pasó aquí con TanStack. No es que la máquina de un mantenedor
00:07:28se viera afectada, sino que fue el flujo de trabajo CICD de TanStack el que fue atacado. Y
00:07:34volveré a eso. Así que es más fácil buscar vulnerabilidades con IA. Es más fácil escribir código,
00:07:40incluyendo código malicioso, por supuesto. Y al mismo tiempo, tenemos esa explosión de software. Tenemos más
00:07:45software escribiéndose que nunca antes. Así que hay más objetivos ahí fuera, incluyendo muchos objetivos
00:07:51que tal vez no se preocupan demasiado por la seguridad. Eso hace que estos ataques sean más interesantes también.
00:07:57Ahora, ¿cómo empezó todo esto? Es muy interesante. Como mencioné, no es un enfoque novedoso,
00:08:03no es uno que nunca hayamos visto antes, pero aun así es bastante elaborado. El equipo de TanStack publicó un
00:08:09post-mortem, un artículo donde explican cómo ocurrió el ataque. Y también lo enlazaré abajo.
00:08:15Pero claro, les daré el resumen aquí porque al final, este ataque de aquí se basó en
00:08:22tres pasos principales, que explicaré en detalle. Un patrón de solicitud pull request pwn. Lo
00:08:30explicaré. Luego, envenenamiento del caché de GitHub Actions a través del límite de confianza de forks
00:08:38y extracción en memoria durante la ejecución de un token OIDC. Vale, ¿qué significa todo eso? De nuevo,
00:08:45pueden leer el artículo para todos los detalles, pero permítanme darles el resumen. Y empecemos con
00:08:50el patrón pull request pwn. ¿Qué es eso? Para entenderlo tenemos que entender
00:08:58que GitHub Actions es, por supuesto, la solución CICD, el producto CICD de GitHub. Y
00:09:05tengo un curso sobre GitHub Actions también, por cierto, si quieres aprender a configurar GitHub Actions,
00:09:10cómo usar el producto para tareas de CICD, cómo publicar tus paquetes o tu sitio web, etc.
00:09:16Ahora, como todas las herramientas de flujo de trabajo CICD, GitHub Actions depende de eventos que activan flujos porque,
00:09:24por supuesto, CICD se trata de hacer algo de forma automatizada. Por ejemplo, lanzar tu sitio web,
00:09:29publicarlo, desplegarlo de forma automatizada cuando haces push a la rama principal, por ejemplo.
00:09:34Así que tienes varios eventos que pueden activar un flujo y push es un evento, por ejemplo,
00:09:40de modo que puedes decir, vale, si hago push a la rama principal, por ejemplo, puedes filtrar por
00:09:44diferentes ramas. Entonces quiero ejecutar ciertas tareas. Quiero instalar mis dependencias. Quiero
00:09:49construir el proyecto. Quiero subirlo a mi servidor. Eso es lo que podrías hacer. Ahora, otro activador
00:09:56es pull_request_target. Este activador se activa si se ha abierto una pull request para tu
00:10:05repositorio. Y eso, por supuesto, significa que cualquiera puede hacer un fork de tu repositorio, hacer algo allí, hacer push
00:10:14en su fork, y luego abrir una pull request con tu repositorio. Y eso activaría
00:10:19este flujo de trabajo. ¿Suena peligroso? Bueno, lo es un poco. Y es lo que inició este ataque.
00:10:25También existe el activador pull_request. Hablé de pull_request_target antes,
00:10:31pero también tenemos pull_request, que funciona igual, pero pull_request ejecuta el flujo
00:10:38CICD en el contexto del repositorio fork. Así que cualquier cosa maliciosa que esté pasando allí,
00:10:45pasa en el repositorio fork, no en el repositorio base. Así que esto no es un problema.
00:10:52pull_request_target, por otro lado, se ejecuta en el contexto del repositorio base. Y eso, por supuesto,
00:10:58es potencialmente peligroso. Es potencialmente peligroso porque cualquiera puede abrir una pull request. Y,
00:11:04por supuesto, lo que pasó en este caso con el ataque a TanStack, en esa pull request, en ese
00:11:10fork, el atacante incluyó el código malicioso, el código del gusano, el malware en el repositorio de TanStack,
00:11:20en el fork del mismo, pero lo incluyó allí. Luego el atacante abrió la pull request,
00:11:26y eso llevó a que se ejecutara pull_request_target. Y luego, como mencioné, eso inicia un
00:11:33runner de GitHub Actions, y se ejecuta en el contexto del repositorio base. ¿Qué significa esto?
00:11:40Esto no significa que el atacante obtenga acceso al código base o pueda fusionar el código malicioso
00:11:46en el repositorio, sino que significa que, por ejemplo, el caché que se usa allí
00:11:53se compartirá con ejecuciones posteriores de GitHub Actions que provengan del repositorio base,
00:12:00potencialmente de ganchos o activadores de eventos totalmente diferentes como el activador push.
00:12:05Lo siguiente que ocurrió fue el envenenamiento del caché. Pero ¿qué significa esto? Bueno,
00:12:11el atacante añadió código a su fork para asegurarse de que cuando la GitHub Action
00:12:17se ejecutara para el activador pull_request_target, ejecutaría un comando, el comando hashfiles,
00:12:23que es soportado por GitHub Actions, para guardar algo en el caché de GitHub Actions. Ahora,
00:12:28¿de qué trata ese caché? La idea detrás del caché de GitHub Actions simplemente es acelerar
00:12:33esos flujos de trabajo de GitHub Actions. Así que puedes, por ejemplo, hashear dependencias. La idea es que
00:12:39si una dependencia de la que depende tu paquete no ha cambiado, ¿por qué pasar por todo el
00:12:46proceso de instalación de nuevo? Eso lleva tiempo, y el tiempo es dinero porque se te factura por el
00:12:52tiempo de ejecución de tu flujo de GitHub Actions. Y por supuesto, no quieres tener flujos que
00:12:56tarden una eternidad. Así que en la mayoría de los flujos, claro, por ejemplo, al construir los paquetes de TanStack,
00:13:00instalas las dependencias de los mismos, y luego haces el paso de compilación y construyes
00:13:06tu paquete de TanStack. De nuevo, si esas dependencias de TanStack no han cambiado,
00:13:12¿por qué reinstalarlas? Esa es la idea del caché. Y tiene sentido. Claro, el problema es que
00:13:18como esa ejecución de pull_request_target y otras ejecuciones de GitHub Actions,
00:13:24como las del activador push, comparten el mismo contexto, comparten el mismo caché. Y ahí es
00:13:31donde entra el envenenamiento del caché, porque el atacante pudo cachear una versión maliciosa o poner
00:13:39ese código malicioso en una dependencia de TanStack, por así decirlo, y cachearla. Entonces el atacante
00:13:46solo tuvo que esperar a que se ejecutara un flujo normal de GitHub Actions para los paquetes de TanStack.
00:13:53O sea, que algún mantenedor hiciera push de algún código, y entonces esa otra ejecución de GitHub Actions reutilizaría
00:14:01el mismo caché que fue configurado por la ejecución maliciosa anterior, y ahora extraería el
00:14:08caché envenenado preparado, que incluía el código malicioso. Así es como el código malicioso
00:14:13pasó del fork a la ejecución normal de GitHub Actions para un push normal de un mantenedor común
00:14:21que no ha sido afectado por ningún código malicioso. Así es como se usó el caché como un vehículo
00:14:28de transporte entre estas dos ejecuciones de GitHub Action al final. Y luego, como tercer paso, una vez que el
00:14:35código malicioso llegó a una ejecución regular de un flujo CICD de TanStack, debido a ese evento
00:14:44de push, robó un token de NPM de corta duración, un token OIDC al final, para publicar una versión maliciosa
00:14:54del paquete TanStack. Ahora, ¿a qué me refiero aquí? NPM tiene esa característica, que se llama
00:15:00trusted publishing (publicación de confianza), que en teoría hace que publicar paquetes en NPM sea más seguro, porque
00:15:04hay básicamente dos formas de publicar un paquete en NPM, se podría decir. Una es que creas un
00:15:11token con tu cuenta de NPM y lo usas para publicar nuevas versiones de tu paquete. El problema
00:15:19es que si ese token es robado, cualquiera puede publicar una nueva versión de ese paquete. Para aumentar la
00:15:26seguridad, existe este proceso de trusted publishing donde NPM dice no, no puedes publicar paquetes desde
00:15:33tu máquina, tienes que pasar por uno de estos proveedores de confianza, siendo GitHub Actions uno de
00:15:37ellos, y hay una integración de trusted publishing para GitHub Actions que puedes configurar. Y entonces,
00:15:44como parte de ese proceso de publicación confiable, se recuperará un token de publicación de corta duración
00:15:50o se solicitará. Y luego ese token de corta duración se usará para firmar esa nueva versión
00:15:57del paquete que se está publicando. Así que, en teoría, la idea es que el token es difícil de robar porque
00:16:03no está en la máquina de ningún mantenedor. Y además, es de corta duración. Incluso si fuera robado,
00:16:08no está activo por mucho tiempo. El problema, por supuesto, es que si el código que se ejecuta en el
00:16:15flujo CICD que solicita ese token confiable, si ese código ha sido afectado, entonces ese código
00:16:21malicioso tiene acceso a este nuevo token de publicación confiable de corta duración. Y eso es lo que pasó
00:16:27aquí. Así que ese código malicioso abusó de este token o usó este token para luego publicar una nueva versión
00:16:36del paquete TanStack. Ahora, curiosamente, este ataque en realidad falló un poco porque sí
00:16:44obtuvo ese token confiable y lo usó para contactar con la API de NPM para publicar una nueva versión
00:16:52del paquete TanStack que incluía este gusano, que incluía el código malicioso. Pero en realidad
00:16:58terminó en un flujo de GitHub Actions que no pudo completarse porque había algo mal en
00:17:06el código que se subió a CICD. Así que si los atacantes hubieran prestado atención para ejecutar su
00:17:12ataque en un momento en que se subiera código válido, entonces por supuesto este flujo se habría
00:17:19completado y no habrían tenido que depender de publicar un paquete malicioso manualmente contactando
00:17:26con la API de NPM, sino que podrían haber inyectado el código malicioso en este flujo como
00:17:32hicieron, dejar que este flujo terminara con éxito y entonces una versión comprometida de TanStack se habría
00:17:38publicado pareciendo muy válida porque fue un push normal de un mantenedor y el flujo
00:17:45terminó con éxito. La forma en que funcionó este ataque, debido a que ese flujo de trabajo no terminó con éxito,
00:17:51hizo que fuera un poco más fácil pillar lo que estaba pasando por parte de un colaborador externo aquí al final,
00:18:00porque se podía ver que se publicó una nueva versión de los paquetes de TanStack a pesar de que el
00:18:05flujo de GitHub Actions falló, por lo que no debería haberse publicado ninguna versión nueva. Así que se podía ver un
00:18:12desajuste allí, lo que facilitó un poco la detección de este ataque, que es una parte donde los
00:18:19mantenedores de TanStack y todos nosotros tuvimos suerte. No obstante, un ataque bastante elaborado, como
00:18:26probablemente puedan notar, que funcionó totalmente sin comprometer la máquina de nadie y, aunque se detectó
00:18:32rápido, hizo un daño serio porque, como mencioné, todavía se está propagando y eso fue un episodio
00:18:41largo sobre todo eso, lo sé, pero realmente quiero enfatizar que tienen que trabajar en hacer su sistema
00:18:49seguro, como compartí antes, como comparto en este video, quieren asegurarse de reducir el
00:18:56peligro de verse afectados; este ataque de nuevo se pilló rápido y aun así se sigue propagando,
00:19:05así que aún no ha terminado y es posible que no todos los ataques se pillen tan rápido
00:19:11en el futuro; como mencioné, tuvieron un poco de suerte aquí, podría haber sido más difícil detectar este
00:19:18ataque, entonces tal vez el daño sería aún mayor; pero ya es bastante grande aquí y
00:19:24no ha terminado, y veremos más ataques así, estoy seguro, porque como mencioné, la superficie de ataque
00:19:31se está volviendo más grande e interesante, hay más gente escribiendo código, mucha gente que
00:19:36no sabe lo que está haciendo y la IA ayuda a ejecutar tales ataques; así que sí, esto es lo que está pasando
00:19:42ahora mismo, si no tienen que hacerlo, quizás no instalen nada, comprueben dos veces su configuración y
00:19:48encontrarán todos los enlaces abajo si quieren profundizar, si quieren ver la lista completa de paquetes
00:19:51afectados y demás.
Community Posts
No posts yet. Be the first to write about this video!
Write about this video