Ladrón de secretos wfx en GitHub Actions: cómo rastrearlo cuando rotar claves no basta
El ladrón de secretos wfx de GitHub Actions usó tokens robados pero válidos de cuentas reales de desarrolladores y bots, abriendo pull requests y subiendo commits como lo haría un desarrollador. Te explicamos por qué rotar claves no cierra el compromiso y en qué orden rastrear en GitHub, Entra, AWS y los proveedores de IA.
El 10 de noviembre de 2026, una campaña de robo de credenciales que los investigadores llaman wfx (también reportada como wfx-loot y WFX Phantom) empezó a introducir ladrones de secretos de CI en repositorios de GitHub a gran escala. Los datos de SafeDep muestran commits maliciosos llegando desde las 12:46 UTC del 10 de noviembre.
La reacción instintiva es rotarlo todo. Debes rotar, pero la rotación por sí sola puede dejarle al atacante una vía de regreso operativa a través de configuraciones de confianza que ningún secreto controla.
Qué es wfx y por qué parece trabajo normal de desarrollo
En el centro de esto no hay ningún fallo de GitHub Actions. El análisis de StepSecurity indica que el atacante tiene tokens válidos de cuentas reales de desarrolladores y bots, y los usa como lo haría un desarrollador: abriendo pull requests y subiendo commits. Nada en tu feed de actividad parece un exploit. Parece un compañero, o un bot, haciendo trabajo rutinario.
La escala es grande. Aikido informa que 4,837 cuentas comprometidas abrieron pull requests de sondeo en 61,764 repositorios, y que al menos 1,835 repositorios ejecutaron la carga maliciosa y sufrieron la exfiltración de credenciales. SafeDep contó de forma independiente 61,879 pull requests de sondeo en 61,734 repositorios desde 4,833 cuentas, con el 91% todavía abiertos. StepSecurity reportó más de 63,000 pull requests de sondeo a las 07:40 UTC del 12 de noviembre, alrededor del 90% todavía abiertos, con nuevos apareciendo cada pocos minutos.
Por qué difieren las cifras de los investigadores
Cada recuento mide algo distinto, tomado en un momento distinto, así que las cifras se complementan en lugar de competir. SafeDep contó 8,093 repositorios que recibieron commits maliciosos entre las 12:46 UTC del 10 de noviembre y las 04:36 UTC del 12 de noviembre, y la campaña seguía activa cuando se realizó esa búsqueda. SecurityWeek señala que la cifra de commits no indica necesariamente una ejecución exitosa, mientras que la cifra de Aikido de más de 1,800 repositorios refleja señales de que el ladrón llegó a ejecutarse. El propio conjunto de datos de GitGuardian contiene 28,500 parches con la carga maliciosa procedentes de 2,367 cuentas en 17,715 repositorios.
Un pull request de sondeo significa que una cuenta intentó entrar, un commit malicioso significa que tenía acceso de escritura, y una ejecución confirmada significa que probablemente salieron secretos. Cuál de esos tres casos te aplica debería orientar lo que hagas a continuación, y solo tus propios registros pueden decirte cuál es.
Cómo llega el ladrón a los secretos de CI
Los pull requests de sondeo prueban el acceso
Sugerimos tratar cualquier pull request de sondeo como una señal de que alguien probó hasta dónde podía llegar un token robado. Help Net Security informa que 10,431 de los pull requests de sondeo entraron en repositorios que no pertenecían a la cuenta, alcanzados mediante acceso de colaborador o de organización, por lo que un solo token robado expone todos los proyectos en los que su titular puede escribir, sea quien sea el dueño del repositorio.
La inyección en workflows fue la principal vía de entrega
Una vez confirmado el acceso, el siguiente paso habitual es inyectar el ladrón en un workflow existente. StepSecurity encontró más de 21,000 commits con el mensaje ci: refresh build cache entre el 10 y el 12 de noviembre. SafeDep encontró 1,343 repositorios en los que el autor del commit malicioso era una cuenta distinta del propietario, como un colaborador o un bot. Esa segunda cifra importa para delimitar el alcance, porque cuando se roba el token de un colaborador o de un bot, el commit malicioso llega a tu repositorio con su nombre, y una revisión que solo mire la actividad del propietario no lo detectará.
La retención de GitHub frenó una variante, pero no la otra
GitGuardian informa que todas las ejecuciones de la carga maliciosa de noviembre que todavía podía observar a partir de cambios en archivos de workflow quedaron en action_required y nunca arrancaron. La variante del hook de npm no fue retenida: en una muestra de 19 repositorios donde el script se ejecutó, 18 reportaron una exfiltración exitosa. Nuestra interpretación es que un hook de dependencia se apoya en un workflow que ya existe en lugar de llegar como un cambio en un archivo de workflow, así que un proceso de revisión centrado solo en archivos de workflow puede no detectarlo. Para los defensores, esto implica revisar los manifiestos de dependencias con la misma sospecha que los archivos de workflow.
Otras vías: GitHub Apps y exfiltración por Telegram
No todos los tokens robados eran personales. StepSecurity descubrió que 173 pull requests de sondeo, abiertos desde 19 cuentas, se hicieron a través de la GitHub App de Fly.io (app ID 34557). Tu delimitación del alcance debe cubrir las autorizaciones OAuth y las instalaciones de GitHub Apps, además de los tokens de acceso personal. La exfiltración también ha cambiado. Las primeras copias enviaban datos a direcciones IP concretas, y StepSecurity informa que el paso a Telegram significa que las listas de bloqueo construidas con las direcciones IP del 10 de noviembre no detectan las copias más recientes. Una coincidencia con esas direcciones sigue mereciendo una investigación, pero un resultado vacío de la lista de bloqueo te dice muy poco sobre si salieron datos.
Por qué rotar claves no pone fin al compromiso
GitHub diseñó su integración OIDC para limitar el daño. La documentación de GitHub explica que el proveedor de nube emite un token de acceso de corta duración que solo es válido para un único job y luego caduca. Un token OIDC robado por sí solo no vale mucho, así que un atacante que quiera quedarse tiene que convertir esa breve ventana en una relación de confianza duradera.
Credenciales de identidad federada de Entra como puerta trasera
En Azure, la credencial de identidad federada es la herramienta obvia para eso. Microsoft la describe como una credencial que crea una relación de confianza entre una aplicación y un proveedor de identidad externo. Aikido informa que, una vez instalada esta puerta trasera, cualquier workflow de ese repositorio puede autenticarse en Azure sin un secreto almacenado, incluso después de rotar todos los tokens.
Políticas de confianza de AWS con un alcance laxo para GitHub OIDC
En AWS, la exposición está en las políticas de confianza de los roles. AWS advierte que si no limitas la clave de condición token.actions.githubusercontent.com:sub a una organización o repositorio concretos, GitHub Actions de organizaciones o repositorios fuera de tu control pueden asumir roles asociados al proveedor de identidad de GitHub en tu cuenta.
La rotación reemplaza los secretos robados, pero deja la configuración de confianza exactamente como la dejó el atacante, y ese es el punto que la dirección más necesita escuchar antes de dar por completa una respuesta.
La caza de wfx: un orden de operaciones
Paso 1: Delimitar las identidades
Enumera todas las cuentas humanas, bots y GitHub Apps con acceso de escritura en tus organizaciones, incluidos los colaboradores externos. Cualquier cuenta que aparezca en pull requests de sondeo es de alto riesgo. Marca también las cuentas afectadas en la ola GhostAction de octubre: Aikido encontró que esas cuentas tenían una probabilidad significativamente mayor que la de referencia de verse afectadas por wfx, y GitGuardian encontró que 431 cuentas de wfx, alrededor del 20%, ya habían sido comprometidas en GhostAction.
Paso 2: Buscar en GitHub
Busca en todos los repositorios en los que tus cuentas pueden escribir, no solo en los que son tuyos. Busca:
- Pull requests de sondeo, abiertos o cerrados, de cuentas que no esperarías.
- Commits titulados
ci: refresh build cache, en la rama por defecto y en otras ramas. - Cambios en archivos bajo
.github/workflows/desde el 10 de noviembre. - Cambios en los scripts de ciclo de vida de
package.json, comopreinstall,installypostinstall.
Paso 3: Revisar el historial de ejecuciones de workflows
Sugerimos comparar el historial de ejecuciones de workflows con el registro de auditoría de tu organización y anotar las ejecuciones que se eliminaron, quién las eliminó y cuándo. Donde se confirme la ejecución, asume que todos los secretos disponibles para ese job quedaron expuestos.
Paso 4: Revisar las credenciales federadas de Microsoft Entra
Sugerimos enumerar las credenciales de identidad federada de cada registro de aplicación y de cada identidad administrada asignada por el usuario. Investiga cualquier cosa que no hayas creado, cualquier emisor o sujeto inesperado y cualquier sujeto que apunte a un repositorio, rama o entorno que no reconozcas. No hemos encontrado ninguna fuente de un proveedor identificado que confirme un patrón de nombres concreto para las credenciales maliciosas, así que trata cualquier nombre que circule de manera informal, como wfx-ci-*, como una pista sin verificar y no como un indicador, y recuerda que una credencial renombrada no coincidiría en ningún caso. Sugerimos usar tus registros de auditoría para establecer cuándo se añadió cada credencial y quién lo hizo, lo que a nuestro juicio es una prueba más fiable que cualquier nombre.
Paso 5: Revisar las políticas de confianza de AWS
Revisa todos los roles de IAM que confían en el proveedor OIDC de GitHub. La condición sub debería restringirse a organizaciones y repositorios concretos, e idealmente a ramas o entornos concretos. Una condición con un alcance ajustado tiene este aspecto:
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
},
"StringLike": {
"token.actions.githubusercontent.com:sub": "repo:your-org/your-repo:ref:refs/heads/main"
}
}Sugerimos después revisar el registro de auditoría de tu nube en busca de ediciones recientes de políticas de confianza y roles recién creados, así como de asunciones de roles desde repositorios que no esperas.
Paso 6: Revisar el uso de los proveedores de IA
Para cada clave de OpenAI, Anthropic y Gemini a la que CI pudiera acceder, revisa el uso y la facturación. Buscas gasto, modelos, regiones o patrones de solicitudes que no encajen con tus cargas de trabajo. Para las preguntas más generales que conviene plantearse cuando las claves de IA pueden haber sido usadas de forma abusiva, nuestra lista de verificación de riesgos de proveedores de inferencia puede ayudarte.
Paso 7: Conservar las evidencias antes de cambiar nada
Exporta los registros de auditoría, los registros de ejecuciones de workflows, los metadatos de pull requests y commits, las entradas de auditoría de Entra y los eventos de CloudTrail antes de empezar la limpieza. Si eliminas un pull request o una credencial maliciosos sin conservar un registro, pierdes la cronología que necesitarás para delimitar el alcance, elaborar informes y realizar cualquier notificación regulatoria.
Contención y recuperación, en secuencia
La secuencia importa porque un secreto rotado puede volver a obtenerse a través de una vía de confianza que sigue activa: mientras una credencial federada maliciosa o una política de confianza laxa sigan funcionando, un workflow controlado por el atacante puede acceder a los nuevos valores con la misma facilidad que a los antiguos. La secuencia que sugerimos:
- Elimina primero el acceso persistente del atacante. Borra las credenciales federadas maliciosas y ajusta las políticas de confianza de AWS antes de la rotación, o al mismo tiempo.
- Revoca el acceso a GitHub. Revoca los tokens de acceso personal comprometidos, las autorizaciones OAuth y las instalaciones de GitHub Apps, incluidas apps de terceros como la que identificó StepSecurity.
- Rota los secretos. Eso incluye los secretos de Actions, las claves de la nube, los tokens de registros de paquetes y las claves de proveedores de IA.
- Limpia el código. Cierra o elimina los pull requests de sondeo y revierte los cambios inyectados en workflows y paquetes en la rama por defecto y en otras ramas. Cualquier pull request de sondeo que quede abierto en una cola de revisión es una oportunidad para que un mantenedor lo fusione por error.
- Termina la limpieza de GhostAction. Aikido encontró más de 100 repositorios en los que wfx se inyectó en archivos de workflow de GhostAction. Si la limpieza de octubre fue solo parcial, termínala ahora.
- Monitoriza. Usa los resultados de la caza como línea base y, a partir de ahora, genera alertas ante nuevas credenciales federadas, ediciones de políticas de confianza y cambios en archivos de workflow.
Refuerzo de las claves de proveedores de IA en CI
A nuestro juicio, las claves de proveedores de IA merecen un lugar explícito en cualquier plan de rotación junto a las credenciales de la nube. La Cloud Security Alliance recomienda proteger las claves de IA con límites de gasto por proyecto y alertas de anomalías de uso, preferir credenciales de corta duración o gestionadas mediante proxy a las claves estáticas en CI, e incluir a los proveedores de IA en los runbooks de rotación ante incidentes junto a las credenciales de la nube y de los registros.
En la práctica, da a cada proyecto su propia clave con su propio límite, para que una sola filtración no pueda agotar un presupuesto compartido. Cuando puedas, enruta las llamadas de CI a través de un proxy interno que guarde la clave real, de modo que el workflow nunca la vea; nuestra guía sobre cómo un proxy de credenciales mantiene las claves de API fuera de los agentes de IA explica ese patrón. La misma disciplina se aplica antes de llegar a CI. Sugerimos revisar también los equipos de los desarrolladores, ya que los archivos de configuración de agentes locales pueden contener credenciales activas; nuestra guía para auditar la configuración de agentes locales y rotar claves expuestas cubre esa comprobación.
Errores comunes en la respuesta a wfx
- Tratar la rotación como la meta. Corrige primero la configuración de confianza (paso 1 de la contención).
- Confiar en las listas de bloqueo de IP del 10 de noviembre. No detectan las copias de la etapa de Telegram.
- Suponer que la retención de GitHub te protegió. Revisa los hooks de
package.json, no solo los archivos de workflow. - Revisar solo los repositorios que son tuyos. Delimita el alcance por acceso de escritura, incluidos los permisos de colaborador y de organización.
- Tomar las cifras públicas como tu veredicto. Las cifras públicas no pueden decirte si te afectó o no; tus propios registros sí.
- Dejar sin terminar la limpieza de GhostAction. Vuelve a revisar las cuentas y los archivos de workflow de octubre.
Salvedades y límites de lo que sabemos
Las cifras públicas proceden de búsquedas en GitHub en momentos concretos mientras la campaña seguía en marcha, así que son instantáneas tomadas en plena campaña y no totales definitivos. Además miden cosas distintas: pull requests abiertos, commits recibidos y ejecución confirmada no son intercambiables, y el recuento de commits de SafeDep no significa necesariamente que la carga maliciosa se ejecutara.
Sugerimos no dar por hecho que los conjuntos de datos externos reflejan lo ocurrido en tus repositorios privados o instancias empresariales. Para la mayoría de las organizaciones, tus propios registros de auditoría, los registros de Entra y CloudTrail son la evidencia principal, y la investigación pública es contexto.
Los indicadores ya han cambiado una vez, como muestra el paso de direcciones IP fijas a Telegram. Los mensajes de commit y los nombres de las credenciales también podrían cambiar, así que consulta los IOC más recientes de los proveedores antes de apoyarte en un único patrón.
La Cloud Security Alliance, citando a GitGuardian, informa que GhostAction usó unas 1,900 cuentas comprometidas para atacar más de 30,000 repositorios en octubre. Junto al recuento de Aikido de 61,764 repositorios para wfx, eso da dos olas separadas por aproximadamente un mes, la segunda de alrededor del doble de tamaño por repositorios atacados. Dos datos no bastan para hablar de una tendencia, aunque sí son motivo suficiente para prepararse ante otra ola.
Esta guía no sustituye a una intervención formal de respuesta a incidentes cuando hay datos regulados o acceso a la nube de producción de por medio.
Puntos clave
- 1El ladrón de secretos wfx de GitHub Actions no explotó ningún fallo de GitHub. Usó tokens robados pero válidos de cuentas reales de desarrolladores y bots, por lo que la actividad parece trabajo normal.
- 2Las cifras públicas difieren porque miden cosas distintas: Aikido reporta al menos 1,835 repositorios donde se ejecutó la carga maliciosa, mientras que SafeDep contó 8,093 repositorios que recibieron commits maliciosos.
- 3Un solo token robado expone todos los repositorios en los que su titular puede escribir. Delimita el alcance por permisos de cuenta y autorizaciones de apps, no por la propiedad del repositorio.
- 4GitHub retuvo en action_required las cargas maliciosas de archivos de workflow, pero la variante del hook de npm pasó: 18 de 19 repositorios de la muestra reportaron una exfiltración exitosa.
- 5Rotar no basta. Las credenciales federadas maliciosas de Entra y las políticas de confianza de AWS con un alcance laxo pueden dejar volver al atacante después de rotar todos los tokens.
- 6Corrige primero la configuración de confianza, luego revoca el acceso a GitHub y después rota. Conserva las evidencias antes de cualquier limpieza.
- 7Protege las claves de proveedores de IA con límites de gasto por proyecto y alertas de anomalías, prefiere credenciales de corta duración o gestionadas mediante proxy e inclúyelas en los runbooks de rotación.
Conclusión
wfx no necesitó ningún fallo en el pipeline; actuó a través de las identidades y las configuraciones de confianza que lo rodean. El atacante tenía tokens válidos de cuentas reales de desarrolladores y bots y los usó como lo haría un desarrollador, abriendo pull requests y subiendo commits. En Azure, Aikido informa que una puerta trasera de identidad federada permite que cualquier workflow de un repositorio afectado se autentique sin un secreto almacenado, incluso después de rotar todos los tokens. Por eso un sprint de rotación puede parecer un avance mientras una credencial federada maliciosa o una política de confianza laxa siguen funcionando.
Una respuesta sólida sigue un orden claro: delimita todas las cuentas y apps que pueden escribir en tu código, busca en GitHub pull requests de sondeo, commits inyectados, cambios en hooks e historiales de ejecución de workflows sospechosos, y revisa las credenciales federadas de Entra y las políticas de confianza de AWS antes de rotar nada. Revisa el uso de los proveedores de IA, conserva un registro de las evidencias y termina cualquier limpieza pendiente de GhostAction. Trata las cifras públicas como contexto y no como un veredicto sobre tu propia exposición. Si la caza revela cambios de confianza que no puedes explicar, o hay datos regulados de por medio, recurre a un servicio formal de respuesta a incidentes.
Preguntas frecuentes
¿Cómo sé si mi organización se vio afectada por la campaña wfx?
Busca en todos los repositorios en los que tus cuentas pueden escribir pull requests de sondeo de cuentas inesperadas, commits titulados 'ci: refresh build cache' y cambios en archivos de workflow o en hooks de ciclo de vida de package.json desde el 10 de noviembre. StepSecurity encontró más de 21,000 commits con ese mensaje entre el 10 y el 12 de noviembre. También sugerimos comparar el historial de ejecuciones de workflows con tu registro de auditoría, incluidas las ejecuciones que se hayan eliminado.
¿Por qué no basta con rotar todos mis secretos para expulsar al atacante?
Es posible que el atacante haya creado una vía de confianza que no depende de ningún secreto. Aikido informa que, una vez instalada una puerta trasera de identidad federada en Azure, cualquier workflow de ese repositorio puede autenticarse en Azure incluso después de rotar todos los tokens. En AWS, una política de confianza de rol que no restringe la condición sub permite que workflows fuera de tu control asuman el rol. Corrige primero esas configuraciones de confianza y después rota.
¿Cómo debe delimitarse una política de confianza de AWS IAM para GitHub OIDC?
AWS advierte que si no limitas token.actions.githubusercontent.com:sub a una organización o repositorio concretos, GitHub Actions fuera de tu control pueden asumir el rol. Restringe sub a repositorios concretos, idealmente también a ramas o entornos concretos, y comprueba el valor de aud. Después revisa CloudTrail en busca de ediciones recientes de políticas de confianza.
¿Bloqueó GitHub el ataque?
En parte. GitGuardian informa que todas las ejecuciones de la carga maliciosa de noviembre que todavía podía observar a partir de cambios en archivos de workflow quedaron retenidas en action_required y nunca arrancaron. La variante del hook de npm fue otra historia: en una muestra de 19 repositorios donde se ejecutó el script, 18 reportaron una exfiltración exitosa. Que los cambios de workflow quedaran retenidos no significa que estés a salvo.
Hicimos la limpieza después de GhostAction. ¿Estamos a salvo?
No necesariamente. GitGuardian encontró que 431 cuentas de wfx, alrededor del 20%, ya habían sido comprometidas en GhostAction, y Aikido encontró más de 100 repositorios en los que wfx se inyectó en archivos de workflow de GhostAction. Vuelve a revisar esas cuentas y repositorios como parte de esta caza.
¿Cómo deben protegerse las claves de proveedores de IA usadas en CI después de wfx?
La Cloud Security Alliance recomienda límites de gasto por proyecto y alertas de anomalías de uso, credenciales de corta duración o gestionadas mediante proxy en lugar de claves estáticas en CI, e incluir a los proveedores de IA en los runbooks de rotación ante incidentes junto a las credenciales de la nube y de los registros. Revisa el uso y la facturación de cada clave de OpenAI, Anthropic y Gemini a la que CI pudiera acceder.
Fuentes
- https://www.aikido.dev/blog/compromised-github-accounts-push-ci-secret-stealer-to-tens-of-thousands-of-repositories
- https://www.stepsecurity.io/blog/wfx-phantom-the-github-actions-secret-stealer
- https://labs.cloudsecurityalliance.org/research/csa-research-note-wfx-github-ci-secret-stealer-20261112-csa/
- https://safedep.io/blog/github-actions-wfx-credential-stealer
- https://blog.gitguardian.com/wfx-loot-a-ci-secret-stealer-pushed-with-stolen-github-credentials/
- https://www.securityweek.com/attacker-targets-60000-github-repositories-in-credential-theft-campaign/
- https://www.helpnetsecurity.com/2026/11/12/wfx-loot-github-actions-secret-stealer/
- https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation-create-trust
- https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-idp_oidc.html
- https://docs.github.com/en/actions/concepts/security/openid-connect
Escrito por
Hamza DiazHamza Diaz es el fundador de Optijara, donde crea agentes de IA prácticos, sistemas de automatización y flujos de trabajo de Copilot para empresas de servicios. Escribe sobre operaciones de IA, estrategia de agentes e implementación real para equipos que quieren sistemas útiles en lugar de promesas vacías.
