TeamPCP Cascade: cuando tu herramienta de seguridad es la puerta trasera
El 27 de febrero de 2026, un bot llamado hackerbot-claw abrió un Pull Request contra el repositorio de Trivy, el escáner de seguridad open source más usado en pipelines de CI/CD. El PR estuvo abierto dos minutos. Un maintainer lo rechazó y lo cerró sin escalar.
Dieciocho días después, TeamPCP lanzó un ataque coordinado en tres vectores que comprometió ~500.000 pipelines, envenenó 82 tags de GitHub Actions y terminó backdooreando LiteLLM: el proxy que centraliza todas las API keys de IA de una organización.
El patrón que nadie detuvo
El PR aprovechó un workflow con pull_request_target — una configuración documentada como peligrosa desde 2021 (el patrón “Pwn Request”). Eso ejecutó código del fork con acceso al GITHUB_TOKEN del repo base. En minutos, las credenciales estaban exfiltradas.
La respuesta de Aqua Security rotó credenciales de forma no-atómica — en días, no en un bloque sincronizado. Durante ese intervalo, TeamPCP generó tokens de reemplazo con el service account todavía válido. Acceso residual: 18 días.
El 19 de marzo usaron ese acceso para:
- Force-push de 75 tags de
trivy-action+ 7 desetup-trivyen 17 minutos - Scraping de memoria del proceso
Runner.Workeren cada pipeline víctima - Recuperación de
GITHUB_TOKEN,AWS_SECRET_ACCESS_KEY,PYPI_API_TOKEN,NPM_TOKENy más
Los secrets marcados como *** en los logs de Actions no están protegidos: el masking es solo un filtro de display. El secreto vive en plaintext en la memoria del runner, y cualquier código ejecutándose en el mismo proceso puede leerlo.
El giro: LiteLLM como vault de credenciales de IA
Con tokens de PyPI recuperados de los pipelines comprometidos, TeamPCP publicó LiteLLM 1.82.7 y 1.82.8 en PyPI el 24 de marzo. Ventana de exposición: 46 minutos a 95 millones de descargas mensuales.
El código malicioso nunca estuvo en el repositorio de GitHub de LiteLLM. La inyección ocurrió post-build, dentro del wheel, antes del upload a PyPI. pip no detectó nada porque verifica consistencia interna del paquete, no fidelidad con el source.
La versión 1.82.8 agregó litellm_init.pth: un archivo .pth de Python que ejecuta el payload de exfiltración de credenciales en cada invocación de Python del sistema — sin importar LiteLLM, sin acción del usuario.
LiteLLM no es solo un paquete más comprometido. Es el vault de credenciales de IA: un proxy que, en producción, tiene acceso a cada request, cada response y cada system prompt que pasa por él hacia OpenAI, Anthropic, Bedrock y el resto. Un proxy comprometido puede loggear, modificar y redirigir todo eso, indefinidamente, hasta que el equipo actualice la versión.
Lo que tenés que llevarte
-
pull_request_targetcon código de forks = vector de entrada. Auditá tus workflows. Si un workflow en el contexto base ejecuta código de un fork, cualquiera puede abrir un PR y correr código con tus secrets. -
La rotación de credenciales debe ser atómica. Si un atacante tiene sesiones activas, una rotación escalonada le da tiempo para renovar tokens antes de que expiren.
-
Pinear por digest, no por tag. Los tags son mutables — pueden apuntar a contenido diferente en cualquier momento.
aquasec/trivy@sha256:...es inmutable. -
Los AI gateways son una nueva categoría de target. La blast radius de comprometer un proxy de IA no escala con el tamaño de una organización: escala con todas las organizaciones que lo usan simultáneamente.
📖 Fuente original: Análisis forense completo en Part I: Twenty Days of Silent Access y Part II: Backdooring the AI Credentials Vault — por Daniel Malvaceda en pipebreach.com.