- La GitHub Action oficial fue manipulada mediante una actualización forzada de etiquetas, provocando un ataque a la cadena de suministro que distribuyó malware
- El atacante reemplazó 75 de 76 etiquetas con commits maliciosos, afectando a más de 10 mil workflows aproximadamente
- El script alterado opera en tres fases: recolección, cifrado y exfiltración de secretos, e incluye código del stealer TeamPCP Cloud
- Las etiquetas comprometidas siguen activas, y se confirmó que solo @0.35.0 o un commit SHA específico son seguros
- Es obligatorio reemplazar todas las credenciales y usar commit SHA fijado, y también se confirmó la misma contaminación en imágenes de Docker Hub
Resumen del ataque a la cadena de suministro de Trivy GitHub Actions
- La GitHub Action oficial de Trivy (
aquasecurity/trivy-action) fue manipulada por un atacante mediante actualización forzada de etiquetas (force-push), en un incidente que distribuyó código malicioso
- El atacante reemplazó 75 de 76 etiquetas de versión con commits maliciosos, manipulándolas para que se ejecutaran automáticamente en pipelines de CI/CD
- Aproximadamente más de 10,000 archivos de workflow de GitHub referencian esta acción, por lo que el alcance potencial es amplio
- Las etiquetas infectadas siguen activas, y se confirmó que @0.35.0 es la única versión segura
- Socket detectó en tiempo real 182 eventos de GitHub Action maliciosos desde las 19:15 UTC, clasificados como Backdoor, Infostealer y Reconnaissance
Causa del ataque y cómo se llevó a cabo
- Según los mantenedores de Trivy, este ataque ocurrió por el robo de credenciales con permisos de escritura
- En una intrusión previa ocurrida a inicios de marzo se filtraron secretos del entorno de CI, y el proceso de rotación no fue completo, por lo que algunas credenciales nuevas quedaron en manos del atacante
- El atacante usó esas credenciales para realizar actualizaciones autenticadas de etiquetas sin explotar ninguna vulnerabilidad propia de GitHub
- En lugar de hacer push a una rama o crear un release, el atacante sobrescribió por la fuerza etiquetas existentes con nuevos commits
- Cada etiqueta fue falsificada para parecer legítima, copiando los metadatos del commit original como autor, correo, timestamp y mensaje del commit
- Sin embargo, mientras los commits originales estaban firmados con GPG, los commits del atacante carecían de firma, y la fecha del commit padre no coincidía al estar fijada en 2026
- Incluso si GitHub mostraba la marca de Immutable Release, es posible que el atacante haya publicado el estado malicioso y luego lo haya bloqueado
- Por eso, no se debe confiar en la insignia “Immutable”; la única forma segura de consumo es fijar el commit SHA (pinning)
Estructura de la manipulación de etiquetas
- El atacante creó nuevos commits a partir del commit más reciente de la rama
master (57a97c7e)
- Solo reemplazó el archivo
entrypoint.sh por una versión maliciosa y dejó intacto el resto de los archivos
- Cada etiqueta fue falsificada replicando el número de PR, mensaje de commit e información del autor originales
- En la página de releases de GitHub, si aparece “0 commits to master since this release”, puede servir como indicador visual de una etiqueta manipulada
- La única razón por la que la etiqueta
0.35.0 no fue alterada es que ya apuntaba al HEAD de master
Estructura del payload malicioso
- El
entrypoint.sh alterado tiene 204 líneas en total, con código Infostealer entre las líneas 4 y 105, seguido por el código legítimo de escaneo de Trivy
- El malware se compone de tres etapas
- Etapa 1: Recolección (Collection) — extrae secretos desde la memoria de procesos del runner y desde el sistema de archivos
- Etapa 2: Cifrado (Encryption) — cifra los datos recolectados con AES-256-CBC y RSA-4096
- Etapa 3: Exfiltración (Exfiltration) — los envía a un dominio controlado por el atacante o a la cuenta de GitHub de la víctima
-
Etapa 1: Recolección de secretos
- Lee variables de entorno de procesos del runner de GitHub Actions (
Runner.Worker, Runner.Listener, runsvc, run.sh) desde /proc/<pid>/environ y extrae entradas que contienen las palabras clave env y ssh
- En runners hospedados por GitHub, ejecuta con
sudo un script de volcado de memoria basado en Python para buscar el patrón "isSecret":true dentro de la memoria del proceso Runner.Worker
- En runners self-hosted, ejecuta un recolector de credenciales del sistema de archivos identificado como TeamPCP Cloud stealer
- Incluye una amplia lista de objetivos, como llaves SSH, credenciales de AWS/GCP/Azure, tokens de Kubernetes, configuración de Docker, contraseñas de BD, archivos de entorno, llaves TLS, configuración de VPN, URLs de webhook y llaves de billeteras
-
Etapa 2: Cifrado
- Genera una clave de sesión de 32 bytes con
openssl rand y luego cifra los datos con AES-256-CBC
- La clave de sesión se cifra con una clave pública RSA-4096 usando padding OAEP
- Los datos cifrados (
payload.enc) y la clave de sesión (session.key.enc) se agrupan en tpcp.tar.gz
-
Etapa 3: Exfiltración de datos
- Canal primario: envío por HTTPS POST a
https://scan[.]aquasecurtiy[.]org (dominio con typo de aquasecurity)
- Canal secundario: si falla, usa el GitHub Personal Access Token de la víctima para crear un repositorio público llamado
tpcp-docs
- Sube
tpcp.tar.gz como asset de un release → luego el atacante encuentra ese repositorio con búsqueda en GitHub y recolecta los datos
- Al usar infraestructura de GitHub, intenta evadir firewalls y aumenta la probabilidad de evitar la detección
- Por último, elimina archivos temporales para minimizar rastros
Atacante y posible autoría
- En comentarios dentro del código malicioso aparece explícitamente “TeamPCP Cloud stealer”
- TeamPCP (DeadCatx3, PCPcat, ShellForce) es un grupo atacante enfocado en entornos cloud-native, con antecedentes de explotación de vulnerabilidades en Docker API, Kubernetes, Redis y paneles de Ray
- En febrero de 2026, Flare y The Hacker News lo reportaron por campañas de ransomware, robo de datos y minería de criptomonedas
- La capacidad para recolectar claves de validadores de Solana y billeteras de criptomonedas coincide con una motivación financiera
Respuesta y recomendaciones
- Dejar de usar todas las etiquetas de versión de Trivy Action, y usar únicamente el commit SHA
57a97c7e7821a5776cebc9bb87c984fa69cba8f1 o la etiqueta 0.35.0
- Considerar los pipelines infectados como una filtración total de secretos, y reemplazar de inmediato todas las credenciales cloud, llaves SSH, tokens de API, contraseñas de BD y tokens de Docker
- Se recomienda verificar si existe un repositorio
tpcp-docs dentro de la organización de GitHub y revisar los logs de trivy-action ejecutados después del 19 de marzo a las 19:00 UTC
Indicadores de compromiso (IOCs)
- Indicador de red:
scan[.]aquasecurtiy[.]org
- Hash de archivo:
18a24f83e807479438dcab7a1804c51a00dafc1d526698a66e0640d1e5dd671a (entrypoint.sh)
- GitHub Actions infectadas: todas las versiones de
aquasecurity/trivy-action@0.0.1 a @0.34.2 (75 etiquetas en total)
Actualización adicional (22 de marzo)
- También se confirmó en Docker Hub que las imágenes de Trivy (
0.69.4, 0.69.5, 0.69.6, latest) fueron contaminadas con el mismo payload Infostealer
- La etiqueta
latest apuntó a una imagen maliciosa y fue distribuida a usuarios durante el período de exposición
- Más detalles relacionados pueden consultarse en el informe separado de Socket “Trivy Docker Images Compromised”
1 comentarios
Opiniones en Hacker News
Me pregunto por qué GitHub no obliga el versionado inmutable (immutable versioning) para Actions
La guía de seguridad dice que hay que fijar con commit SHA, pero parecería que este problema se podría reducir si directamente no se pudiera publicar una Action sin fijarla
Desde el punto de vista de seguridad, una versión fijada es más segura, pero al mismo tiempo también es riesgoso si las actualizaciones de seguridad no se aplican automáticamente
Al final, hace falta una solución que cumpla con ambas cosas sin perjudicar la productividad
Me dan ganas de llamar a esto la “paradoja del pinning”
Aun así, en algún momento habrá que empezar a cambiarlo
Permitir actualizaciones podría incluso mejorar la seguridad
Es un problema parecido al debate entre enlace estático vs enlace dinámico
Además, la Action de Trivy de todos modos estaba hecha para traer la versión más reciente
Este incidente es una advertencia de que los productos de “seguridad de la cadena de suministro (supply chain security)” en la práctica pueden ser tan vulnerables como la pila que intentan proteger
En particular, las herramientas de seguridad de “ejecútanos en todas partes” crean un nuevo vector de ataque en el que un solo ataque puede poner en riesgo a muchísimos usuarios al mismo tiempo
Al principio pensé que Trivy no había hecho bien la rotación de credenciales (rotation)
Pero explicaron que “durante un proceso de rotación no atómico (non-atomic), el atacante podría haber descubierto el nuevo token”
GitHub no vuelve a mostrar el token después de emitirlo, aunque esto puede variar según el método de autenticación usado
Apenas creó una nueva organización de GitHub, le secuestraron el nombre y tuvo que pedirle a GitHub un proceso de creación atómica
Es un caso en el que encaja perfecto eso de que “hay que escanear vulnerabilidades, no convertirse en una”
Hubo un incidente relacionado: compromiso temporal de la cadena de suministro de Trivy
El 22 de marzo, el atacante publicó imágenes maliciosas de Trivy v0.69.5 y v0.69.6 en DockerHub usando credenciales robadas
(enlace al aviso de seguridad)
Hubo dos incidentes, el 19 y el 22 de marzo, y parece que el atacante mantuvo el acceso de forma continua a pesar de dos rotaciones de credenciales
“Las últimas dos semanas fueron las peores”
Por el hackeo de Trivy, ahora hay que lidiar con una gran cantidad de informes y reuniones de seguridad
La lección es que “hacer software de seguridad no significa necesariamente ser competente”
Nuestro equipo de seguridad también intenta meter un escáner nuevo cada mes, pero si les hubiéramos dado el acceso amplio que piden, ya nos habrían comprometido varias veces
setup-trivyestaba hecha para clonar tal cual la rama principal y ejecutar un script de shellO sea, permitía ejecución arbitraria de código en todos los flujos de trabajo de CI
Aqua sufrió una intrusión a principios de este mes y, después de dos fallas de aislamiento, hasta su cuenta de Docker Hub fue comprometida
Ahora creo que necesitan ayuda de expertos externos
La mayoría no son más que generadores ruidosos de reportes, y si un atacante entra adentro, no pueden defender nada
A un escáner nuevo hay que darle acceso solo a datos de lectura en una sandbox aislada, y no darle permisos de producción hasta que esté suficientemente validado
Si no, es casi lo mismo que subir tus claves secretas a pastebin
Se ha convertido en una cultura de seguridad de “moverse rápido y romperlo todo”
Por eso se ha creado una cultura de adoptar sí o sí software de seguridad de baja calidad
No creo que Trivy en sí sea malo, y en nuestra empresa también lo usamos
Solo que nosotros fijamos las versiones con Nix y escribimos nuestros propios flujos de trabajo de Actions, así que esta intrusión no nos afectó
El atacante pudo hacer una actualización forzada de etiquetas (force-update) estando autenticado
Esto se habría evitado con solo activar la vieja opción de GitHub de “prohibir sobrescribir etiquetas”
Cada vez que se repite un incidente así, me convenzo más de que hacen falta estándares como un Software Building Code
Me pregunto cuántas razones más de este tipo aparecerán en 2026