Qué hace esta herramienta
GitHub suele ser la primera puerta de entrada a la nube: un solo token de acceso personal robado da al atacante tu código fuente, tus pipelines de CI/CD y — a través de los secretos de Actions — tus cuentas cloud. El registro de auditoría de la organización recoge casi todo: quién se autenticó con qué token, desde qué IP, qué clonó, qué ajuste cambió.
Esta herramienta lee esas exportaciones en tu navegador, evalúa un conjunto de reglas de detección publicadas y da un veredicto global (Limpia / Sospechosa / Comprometida), los hallazgos con sus evidencias y técnicas MITRE ATT&CK, una cronología del incidente, un pivote por entidad (actores, tokens, IP, repositorios, workflows, runners, aplicaciones) y un plan de remediación.
Qué puedes soltar
- Registro de auditoría de organización o empresa exportado desde la interfaz web (JSON o CSV).
- Salida de la API REST (GET /orgs/{org}/audit-log, con include=all para los eventos Git), con páginas concatenadas o no.
- Archivos de streaming del registro de auditoría (Amazon S3, Azure Blob, Google Cloud Storage): estructura YYYY/MM/DD/HH/MM/<uuid>.json.log.gz, JSON lines comprimido con gzip — suelta la carpeta entera.
- Exportación de eventos Git (export-<empresa>-<timestamp>.json.gz): git.clone, git.fetch y git.push con metadatos de token.
- Archivos de logs de ejecución de GitHub Actions (el ZIP de «Download log archive»).
- Alertas de secret scanning tal como las devuelve la API REST (JSON).
Qué detecta
Las detecciones son datos, no código: cada regla es una entrada JSON revisable (condiciones, umbral o referencia, gravedad, técnicas ATT&CK, remediación) con casos de prueba positivos y negativos. Las reglas de esta versión:
| Regla | Gravedad | ATT&CK |
|---|---|---|
Un paso del workflow codifica o envía secretosactions-secret-exfil | Crítica | T1552.001, T1567 |
Token usado desde un país nuevotoken-new-country | Alta | T1550.001, T1078.004 |
Clonado masivo de repositoriosgit-clone-burst | Alta | T1213.003 |
Repositorio hecho públicorepo-made-public | Alta | T1567 |
Repositorio transferido fuerarepo-transferred | Alta | T1537 |
Varios repositorios eliminadosrepo-mass-delete | Alta | T1485 |
Nuevo propietario de la organización o empresaowner-granted | Alta | T1098.003 |
Requisito de doble factor desactivadotwo-factor-disabled | Alta | T1556 |
SSO SAML desactivado o reconfiguradosso-changed | Alta | T1556 |
Lista de IP permitidas desactivadaip-allowlist-disabled | Alta | T1562.007 |
Streaming del registro de auditoría eliminado o modificadoaudit-stream-changed | Alta | T1562.008 |
Protección de rama o ruleset eliminadobranch-protection-removed | Alta | T1562 |
Protección de entorno de despliegue eliminadaenvironment-protection-removed | Alta | T1562 |
Cuenta activa desde un país nuevoactor-new-country | Media | T1078.004 |
Muchos archivos de código descargadosarchive-download-burst | Media | T1213.003 |
Acceso admin concedido a un colaboradorcollaborator-admin | Media | T1098 |
Restricciones de aplicaciones de terceros desactivadasoauth-restrictions-disabled | Media | T1562 |
Política de tokens de acceso personal debilitadapat-policy-weakened | Media | T1562 |
Protección de rama eludidabranch-protection-override | Media | T1562 |
Runner autoalojado registradoself-hosted-runner-registered | Media | T1072 |
Cadena codificada larga impresa en un log de workflowactions-encoded-output | Media | T1552.001, T1027 |
Secret scanning encontró un secreto filtradosecret-leak-alert | Media | T1552.001 |
Protección de push de secretos eludidapush-protection-bypass | Media | T1552.001 |
Clave SSH o de despliegue añadidadeploy-key-added | Media | T1098.004 |
Token usado desde una dirección IP nuevatoken-new-ip | Baja | T1550.001 |
Fork de repositorios privados permitidoprivate-forking-enabled | Baja | T1537 |
Secreto de Actions creado o modificadoactions-secret-created | Baja | |
Workflow ejecutado desde una rama nunca vistaworkflow-new-branch | Baja | T1677 |
Token fine-grained solicitado o autorizadofine-grained-token-granted | Baja | T1550.001 |
Aplicación instalada u OAuth aprobadaapp-authorized | Baja | T1528 |
Webhook creadowebhook-created | Baja | T1567 |
Cómo se decide el veredicto
- Comprometida: al menos un hallazgo crítico (por ejemplo, secretos impresos por un workflow), o varios hallazgos distintos de gravedad alta sobre el mismo actor, token o dirección IP.
- Sospechosa: al menos un hallazgo de gravedad alta o media.
- Limpia: ningún hallazgo por encima de baja. Solo cubre lo que contienen los registros — revisa las notas de cobertura (visualización de IP, eventos Git, metadatos de token) y el periodo cubierto.
Cuando se filtraron claves cloud
Los secretos de Actions suelen ser credenciales cloud. Cuando aparecen en las evidencias, el siguiente paso es la propia cuenta cloud — continúa con las herramientas hermanas de esta serie:
Limitaciones
- El registro de auditoría no guarda el contenido de los archivos: un workflow modificado se deduce de las ejecuciones (rama nueva, secretos impresos en el log), no del diff. Revisa tú mismo el historial de .github/workflows.
- Sin «Display IP addresses», las exportaciones no tienen actor_ip y la ubicación es limitada: las detecciones basadas en IP no pueden activarse.
- Los eventos Git (clones, fetches, pushes) solo se conservan 7 días y no están en la exportación JSON/CSV de la interfaz web: sin ellos el clonado masivo es invisible.
- Las reglas son heurísticas con umbrales (10 repositorios clonados en aproximadamente una hora, una referencia de 24 horas para IP y países nuevos): ajústalas a tu organización. Un veredicto limpio no demuestra la ausencia de ataque.
- La tabla muestra los primeros 100 000 eventos; se analizan todos. No se cubren los registros de seguridad de cuentas personales.
Preguntas frecuentes
¿Se suben mis registros de auditoría a algún sitio?
No. El analizador está escrito en Rust, compilado a WebAssembly, y se ejecuta en un Web Worker de tu navegador; los archivos se leen en flujo desde el disco y se descomprimen localmente. No hay ningún punto de subida y la herramienta funciona sin conexión una vez cargada la página.
¿Cómo sé si robaron un token de GitHub?
Busca el mismo hashed_token usado desde una IP o un país nuevos, ráfagas de git.clone sobre muchos repositorios y actividad del token fuera del horario de su propietario. El registro de auditoría guarda hashed_token, programmatic_access_type y token_scopes en los eventos autenticados con token; esta herramienta crea una referencia por token y señala las ubicaciones nuevas.
¿Cómo encuentro a qué token corresponde un hashed_token?
hashed_token es el SHA-256 del token codificado en base64. Si tienes un token candidato, calcúlalo con: echo -n TOKEN | openssl dgst -sha256 -binary | base64 — y busca hashed_token:"VALOR" en el registro de auditoría. Los propietarios de empresa también pueden exportar el inventario de credenciales, que incluye los valores hashed_token.
¿Por qué no veo eventos git.clone?
Los eventos Git no se incluyen en la exportación JSON/CSV del registro de auditoría de la interfaz web. Obtenlos desde el menú «Export Git Events» de la empresa, la API REST con include=git o include=all, o el streaming del registro de auditoría — y rápido: solo se conservan 7 días.
¿Puede un workflow filtrar secretos aunque GitHub los enmascare?
Sí. GitHub sustituye los valores conocidos de los secretos por *** en los logs, pero un script que los codifica en base64 (dos veces, o invertidos) imprime una cadena sin enmascarar que se decodifica en el secreto. Esta herramienta señala los scripts que pasan secretos o el entorno a codificadores o destinos externos, y las cadenas codificadas largas en la salida.
¿Es una herramienta oficial de GitHub?
No. Es una herramienta independiente, no afiliada ni respaldada por GitHub, Inc. Lee los formatos de exportación documentados del registro de auditoría.