La campaña wfx-loot usó 4.837 cuentas ya comprometidas de GitHub para abrir pull requests en 61.764 repositorios desde el 10 de noviembre. Aikido identificó al menos 1.835 repositorios donde se ejecutó una carga que robaba secretos de GitHub Actions y credenciales cloud; el código también podía llegar a paquetes publicados mediante automatizaciones.
Están potencialmente afectados los repositorios en los que una cuenta comprometida podía escribir, incluidos los accesibles por colaboración u organización aunque no pertenecieran a esa cuenta. El primer indicio puede ser un pull request titulado docs: dependency audit notes, procedente de la rama wfx-docs. Aikido advierte que ese pull request era un sondeo de permisos: para saber si hubo robo hay que buscar también los cambios posteriores y señales de ejecución.
Primero, determina si hubo ejecución
Busca en los repositorios a los que tienes acceso pull requests con ese título, además de ramas llamadas chore/ seguidas de ocho caracteres aleatorios. Revisa también commits titulados ci: refresh build cache, chore: add ci helper o chore: add dependency audit workflow. Son indicadores descritos por Aikido; su presencia justifica investigar el repositorio, pero un pull request de sondeo por sí solo no confirma que se exfiltraran credenciales.
La carga se insertó de tres formas: modificando un flujo de GitHub Actions existente, añadiendo un script con un gancho de instalación de npm o creando un flujo nuevo en una rama temporal. Busca cambios en los flujos y scripts, incluidos los que ya hayan sido revertidos. El atacante podía borrar el flujo de ejecución y sus registros en menos de un minuto. Aikido señala que un número de ejecución ausente en el historial puede ser una pista; la falta de registros, artefactos o resúmenes no demuestra que no hubiera robo.
Si el flujo se ejecutó, no limites la revisión a las variables que aparecen en el código del repositorio. La carga podía recoger secretos y variables de Actions, tokens de ejecución, credenciales cloud, archivos de configuración, claves SSH, archivos .env y credenciales de herramientas de desarrollo e IA. Considera expuesto todo lo accesible para los flujos afectados y para el runner donde se ejecutaron.
Pasos para contener el incidente
Identifica el alcance de escritura. Revisa los repositorios propios y aquellos a los que la cuenta podía acceder como colaboradora o por pertenencia a una organización. Aikido contabilizó 10.431 pull requests en repositorios que la cuenta comprometida no poseía. Incluye los proyectos con automatizaciones de publicación: la campaña alcanzó un paquete de Packagist y dos etiquetas de un módulo de Go.
Preserva lo que aún exista. Guarda los pull requests, ramas, commits y registros disponibles para cada repositorio sospechoso antes de limpiar. Anota los cambios y las horas observadas. No dependas del historial de ejecuciones: el atacante podía eliminarlo, y el número de ejecución ausente puede ser el único rastro de que el flujo llegó a correr.
Revoca y rota credenciales accesibles. Si confirmas que la carga se ejecutó, trata como comprometidos los secretos y credenciales disponibles para esos flujos. Incluye las credenciales cloud y de servicios, no solo los secretos de GitHub Actions; prioriza las que podían usar los flujos afectados.
Revisa AWS y Azure en busca de persistencia. La carga tenía funciones para ampliar y mantener el acceso: podía modificar la política de confianza de un rol de AWS y añadir credenciales de identidad federada a aplicaciones de Azure. Comprueba si hay cambios no autorizados en esos permisos y configuraciones. Rotar una clave no basta si también se alteró la forma de conceder acceso.
Inspecciona los runners afectados. El script podía leer el entorno y la memoria de procesos del runner; en runners autogestionados también buscaba credenciales y estado de contenedores. Investiga el runner desde el que corrió el flujo y las credenciales que tenía disponibles. Si hubo una instalación de un paquete sospechoso, considera comprometida la máquina según las indicaciones específicas de Aikido para Packagist.
Comprueba los paquetes afectados. Aikido identifica
digitalelvis/neuronai-studiode Packagist, versión3.14.3, y las etiquetasv1.0.278yv1.0.280degithub.com/onuragtas/docker-env. Aikido recomienda tratar como comprometida cualquier máquina que instalara o abriera la versión de Packagist. En las etiquetas de Go, el payload estaba únicamente en un archivo de flujo de GitHub Actions: Aikido dice que el código fuente y los binarios publicados no cambiaron, aunque recomienda retirar esos paquetes.Escala el análisis a la organización. Comprueba si una misma cuenta abrió pull requests en varios repositorios y si los tokens asociados tenían permisos más amplios. SecurityWeek recoge que los atacantes usaron tokens válidos de cuentas de desarrolladores y bots; no se trató de explotar un fallo de GitHub Actions. Si ves actividad en varios proyectos, revisa también sus integraciones y credenciales cloud disponibles.
Repite la búsqueda después de limpiar. Una vez revocados los accesos y revisados los cambios, vuelve a comprobar ramas, pull requests, flujos y configuraciones cloud. Aikido describe mecanismos diseñados para persistir más allá de una rotación de credenciales; por eso, la respuesta no termina al borrar el archivo malicioso o cerrar el pull request.
Errores que pueden dejar una puerta abierta
No confundas sondeo con ejecución. El pull request de prueba buscaba confirmar que el token tenía permiso de escritura; Aikido indica que era solo la fase inicial. Pero tampoco lo descartes como inocuo: busca los commits y flujos que pudieron seguirlo, y comprueba si hay indicios de ejecución.
No tomes la ausencia de registros como tranquilidad. El atacante revertía cambios y borraba ejecuciones y logs. Según Aikido, tampoco basta con no encontrar artefactos wfx-loot, entradas de caché o resúmenes con WFX-BEGIN: esos canales estaban desactivados en la configuración observada. Un historial aparentemente limpio no descarta el robo.
No te limites a los repositorios propios. Las cuentas comprometidas podían escribir en proyectos de terceros mediante acceso de colaboración o de organización. Revisa todos los repositorios donde esas credenciales tuvieran permiso, incluidos los que publican paquetes automáticamente.
No rotes secretos sin revisar permisos. Aikido documenta funciones para modificar configuraciones de confianza en AWS y Azure. Comprueba si hubo cambios persistentes en esos entornos además de revocar tokens y rotar secretos; de lo contrario, un acceso adicional podría sobrevivir a la rotación.
El umbral práctico es claro: si la carga llegó a ejecutarse, trata como expuesto todo secreto al que podía acceder el flujo y revisa los permisos cloud asociados. Si solo encuentras el pull request de sondeo, continúa investigando los cambios posteriores antes de dar por cerrado el caso.
Fuentes: Help Net Security, MuySeguridad. Seguridad informática., Aikido Security, SecurityWeek, TechRadar