DevOps

Riesgo de Seguridad: Acceso No Revocado en GitHub Expone Repositorios de CrowdSec

TL;DR — Lo que vas a tener al final

  • Tiempo de setup: 2-3 horas para el switch a enforcing.
  • Requisitos: Root, kernel moderno, 2-4 semanas en permissive antes de enforcing.
  • Resultado: Sistema con MAC activo, logs en /var/log/audit/audit.log.
  • Troubleshooting: audit2allow, audit2why, setenforce 0 para emergencias.

De qué va esta historia

El 18 de septiembre de 2026 CrowdSec publicó un comunicado oficial reconociendo que el código fuente de aproximadamente 170 repositorios privados de su organización fue copiado el 22 de mayo de 2026 desde una cuenta de GitHub corporativa. La intrusión no fue detectada hasta cuatro meses después, el 16 de septiembre, cuando Fuites Infos (servicio francés de notificación de filtraciones) les contactó porque el código había empezado a circular en un foro.

Lo que hace a este caso diferente de un leak genérico es la cadena causal: CrowdSec atribuye la intrusión al compromiso de TanStack del 11 de mayo, el mismo ataque de supply chain a npm que cubrimos en detalle en el arresto de TeamPCP en agosto y en el caso del crate malicioso en Crates.io. CrowdSec usaba el componente de TanStack comprometido dentro de su organización en mayo y, según su propio análisis, ese componente estaba backdooreado para extraer una API key con permisos de lectura sobre el codebase privado.

Para un sysadmin Linux esto importa porque CrowdSec no es una empresa cualquiera: es uno de los proyectos open source más usados para reemplazar fail2ban en producción (corren instancias en cientos de miles de servidores). Si su código SaaS está ahora en manos de alguien, la pregunta razonable no es si el producto sigue siendo seguro, sino cuánto tiempo tienes que pensar antes de confiar ciegamente en su pipeline de releases durante los próximos meses.

Lo que CrowdSec confirmó y lo que no

El comunicado del 18 de septiembre es bastante sobrio y merece leerse sin prisa. Las afirmaciones concretas que la empresa hace:

Afirmación Fuente Detalle verificable
170 repos privados copiados el 22 de mayo CrowdSec statement Reportado por Fuites Infos el 16-sept, confirmado internamente
API key extraída durante compromiso TanStack de mayo CrowdSec statement Apunta al backdoor de TanStack npm del 11-may
No se filtraron datos de clientes CrowdSec statement CrowdSec no almacena PII ni logs de clientes
Todo el código afectado fue auditado internamente CrowdSec statement Se rotaron todos los tokens y credenciales relevantes
Vector inicial: componente TanStack comprometido CrowdSec + The Hacker News Mismo vector que usó TeamPCP contra otros blancos

Lo que CrowdSec no confirma es la versión que The Hacker News publicó en su titular: que la intrusión fue por una cuenta de un ex-empleado al que no se le había revocado el acceso. CrowdSec solo dice que el vector fue TanStack y que el código estuvo expuesta durante cuatro meses. Esa diferencia es importante: una cuenta de ex-empleado sin revocar es una falla de offboarding (operacional), mientras que un backdoor en una dependencia upstream es un problema sistémico del modelo de supply chain moderno. Ambas son ciertas simultáneamente, pero la remediación es distinta en cada caso.

Por qué CrowdSec importa aunque no uses su SaaS

CrowdSec tiene dos productos que se confunden constantemente y vale la pena separar:

  • Security Engine (open source, Apache 2.0): el binario que analiza logs, detecta comportamientos anómalos y comparte blocklists con la red comunitaria. Este código sigue siendo público y no fue afectado por la filtración. Si lo instalaste en tu servidor, tu binario es el mismo de antes.
  • CrowdSec Console (SaaS): el panel de gestión que centraliza alertas, decisiones, blocklists y API para entornos multi-servidor. Este sí está dentro del código filtrado. Si usas el SaaS, los tokens de tu organización se rotaron preventivamente, pero los próximos 60 días son zona gris hasta que termine la auditoría completa.

El riesgo operativo real no es que alguien decompile tu binario local — está abierto, no hay nada que decompilar. El riesgo es que un atacante con acceso al código del Console ahora conoce los endpoints internos de la API, los formatos de webhook, los secretos de integración con CAPI (Central API) y los detalles de cómo se generan los decision objects que el engine sube. Esto facilita ataques de impersonation contra tu instancia si el atacante consigue suficiente telemetría.

Lo que el comunicado sí reconoce explícitamente es que la filtración le da a un atacante un mapa más detallado del backend. CrowdSec afirma que el código “ha evolucionado significativamente” en los cuatro meses posteriores a la copia, pero también que monitorearán actividad anómala. En la práctica, eso significa que cualquier release del Console en los próximos meses debe pasar tu propio scrutiny adicional: no es paranoia, es proporcional al incidente.

El vector exacto: cómo TanStack te puede llegar desde tu CI

El postmortem oficial de TanStack del 11 de mayo describe con precisión forense la cadena. Vale la pena entenderla porque se repite en cualquier organización que use JavaScript/TypeScript en su pipeline:

  1. El 10 de mayo, un atacante crea un fork del repositorio TanStack/router con un nombre distinto (configuration) para evadir búsquedas.
  2. El 11 de mayo a las 10:49 UTC, abre un PR contra el repo principal. El PR activa workflows de GitHub Actions que usan pull_request_target, un trigger que ejecuta código del PR con permisos del repo base.
  3. El código del PR incluye un bundle-size.yml que hace checkout del PR y corre pnpm install. La instalación ejecuta scripts de los paquetes, entre ellos uno que lee el ACTIONS_RUNTIME_TOKEN del runner (un token OIDC de GitHub Actions) y lo exfiltra.
  4. Con ese token OIDC, el atacante publica versiones maliciosas de 42 paquetes @tanstack/* entre las 19:20 y las 19:26 UTC.
  5. Cualquier developer o CI que haya corrido npm install contra esas versiones en ese intervalo de 6 minutos queda con credenciales filtradas: AWS IMDS, GCP metadata, Kubernetes service-account tokens, tokens de Vault, GitHub tokens, SSH private keys.

El mismo vector se usó contra CrowdSec: un developer de la organización instaló el paquete comprometido (probablemente como dependencia transitiva de algo más grande), su máquina ejecutó el script de extracción, y de ahí se obtuvo el token con permisos de lectura sobre el codebase privado. CrowdSec no confirma cuál de sus developers fue el paciente cero, pero la mecánica es la que describen arriba.

Para verificar si tu máquina quedó comprometida el 11 de mayo, el procedimiento documentado por TanStack es rotar todas las credenciales accesibles desde el host:

# Lista de credenciales a rotar si instalaste algo el 11-may entre 19:20 y 19:26 UTC:
# AWS: access keys + IMDS ephemeral
# GCP: service account keys + access tokens
# Kubernetes: cluster tokens (kubectl config view --flatten)
# Vault: tokens de aplicación
# GitHub: PATs + GitHub Actions secrets
# NPM: tokens de publish
# SSH: private keys de ~/.ssh
# Verificar qué paquetes tenías instalados ese día:
cat package-lock.json | jq -r '.packages | keys[] | select(test("@tanstack/"))'
# Si aparece algo de la lista de 42 paquetes publicados, rotá TODO lo accesible desde ese host

La auditoría oficial de GitHub sobre este incidente está bajo GHSA-g7cv-rxg3-hmpx y el CVE asociado es CVE-2026-45321 con CVSS 9.6.

Lo que cambia en tu propio pipeline después de CrowdSec

Si eres sysadmin o DevOps y administras pipelines de build, este caso cierra un argumento que ya veníamos sosteniendo en otros posts: el modelo de confianza por nombre de paquete dejó de ser suficiente. El nombre te dice qué pediste, no qué recibiste. La cadena de TanStack del 11-may tuvo versiones firmadas por npm bajo nombres legítimos durante 6 minutos y nadie lo notó hasta que un researcher externo (ashishkurmi de stepsecurity) levantó la alerta.

Las defensas concretas que tienen sentido aplicar después de este caso se solapan con las del caso TeamPCP pero con énfasis distinto:

Capa Acción Bloquea qué
Dependencias npm Habilitar npm config set ignore-scripts true en CI y permitir solo en paquetes nativos conocidos Postinstall que exfiltra secrets durante install
Dependencias npm Pin de versiones a SHA de commit, no a tag mutable Re-publicación maliciosa de una versión legítima
GitHub Actions Reemplazar pull_request_target por pull_request en workflows que no necesitan acceso a secretos del repo base Cache poisoning del fork↔base trust boundary
GitHub Actions Pin de actions de terceros a SHA completo, no a tag Tercero comprometido te compromete a tú
Offboarding Revocar TODAS las credenciales del developer en el mismo día de salida, no después Cuenta de ex-empleado siendo vector 4 meses después
Offboarding Auditar cuentas inactivas >30 días y forzar re-autenticación con 2FA hardware key Cuentas zombie que nadie sabe que existen
Runtime Segmentar secrets por scope: tokens de CI no leen codebase privado Un token comprometido no abre todo el repo

El punto de offboarding es donde el caso CrowdSec según la versión de The Hacker News se separa del comunicado oficial. Si efectivamente fue una cuenta de ex-empleado sin revocar, ese vector sigue vigente: cualquier org con developer turnover mayor a uno por trimestre tiene cuentas dormidas. La remediación operativa es directa — script que recorra la lista de miembros de la org GitHub, compare con la lista de empleados activos, y alerte sobre cualquier delta:

#!/usr/bin/env bash
# audit-github-members.sh
# Lista miembros de la org GitHub y los cruza con tu HR source.
# Requiere: gh CLI autenticado con scope read:org
set -euo pipefail
ORG="${1:?uso: $0 }"
HR_FILE="${2:?ruta al CSV de empleados activos}"
gh api "orgs/$ORG/members?per_page=100" --paginate 
  | jq -r '.[].login' 
  | sort > /tmp/gh-members.txt
cut -d',' -f1 "$HR_FILE" | tail -n +2 | sort > /tmp/hr-active.txt
# Miembros en GitHub que NO están en HR
comm -23 /tmp/gh-members.txt /tmp/hr-active.txt

Correrlo semanalmente es realista. Que devuelva una lista vacía la mayoría de las semanas es el estado correcto. Cuando devuelva algo, eso es alguien que dejó la org pero sigue con acceso — exactamente la falla que según The Hacker News sufrió CrowdSec.

Cuándo NO entrar en pánico

El comunicado de CrowdSec enfatiza tres cosas que vale la pena recordar antes de tomar decisiones drásticas:

  1. El Security Engine open source no fue afectado. Si solo usas el binario local (caso más común en homelabs y servidores chicos), tu instancia sigue siendo exactamente el código que ves en github.com/crowdsecurity/crowdsec. No tienes que hacer nada.
  2. No se filtraron datos de clientes. CrowdSec no almacena logs de clientes en su SaaS, así que no hay base de datos de logs propios comprometida. Lo que se filtró es código, no datos operativos tuyos.
  3. El código afectado es auditado y rotado. CrowdSec rotó tokens, claves y secretos propios. El riesgo residual es que un atacante con el código encuentre una vulnerabilidad nueva antes que los maintainers, pero ese es el modelo estándar de cualquier proyecto open source.

Lo que sí tiene sentido hacer si usas el SaaS:

  • Revisar el audit log de tu consola CrowdSec de los últimos 4 meses buscando IPs o user-agents anómalos.
  • Rotar el API token de tu organización en CrowdSec Console.
  • Si tienes webhooks configurados hacia terceros (Slack, Discord, Teams, Mattermost), verificar que las URLs siguen apuntando a donde deben.
  • Si exportás blocklists via API, monitorear que el endpoint público no haya sido re-enumerado.

Resumen accionable

El caso CrowdSec resume por qué la cadena de supply chain en JavaScript/TypeScript dejó de ser problema teórico. La misma clase de ataque que usó TeamPCP para comprometer 3.800 repos en mayo le sirvió a un atacante (no necesariamente el mismo grupo) para copiar 170 repos privados de una empresa de seguridad francesa cuatro meses después. CrowdSec no es especial por haber sido blanco — es un caso visible porque la empresa decidió publicar el comunicado. Muchos otros probablemente no publicaron nada.

Lo que cambia operativamente para ti:

  • Offboarding de developers = revocar TODO el mismo día, no gradualmente.
  • Pin de dependencias a SHA, no a tag mutable.
  • pull_request_target solo donde realmente lo necesitas, con repository_owner guard explícito.
  • Tokens de CI con scope mínimo: nada de “todo el codebase privado” en un solo token.
  • Auditoría semanal de miembros de la org vs HR activa (el script de arriba es realista).

Ninguna de estas capas te salva sola. La combinación sí — y cada capa es barata de implementar. CrowdSec descubrió el incidente porque un tercero proactivo les avisó; la mayoría de las organizaciones no tienen esa suerte.

Preguntas frecuentes

¿Por qué Riesgo de Seguridad: Acceso No Revocado en GitHub Expone Repositorios de CrowdSec es relevante para sysadmins Linux?

Forma parte del flujo diario de administración. Los conceptos explicados se aplican directamente a servidores en producción y resuelven problemas reales que enfrentan sysadmins hispanohablantes.

¿Qué necesito para empezar con Riesgo de Seguridad: Acceso No?

Distribución Linux actualizada (Debian, Ubuntu, RHEL, Fedora o Arch), acceso root, y conexión a internet. Para producción: entorno de staging separado antes de aplicar cambios.

¿Cuáles son los errores más comunes con Riesgo de Seguridad: Acceso No?

Los tres más frecuentes: (1) saltar la lectura de logs, (2) aplicar cambios directos en producción sin probar, (3) olvidar permisos y ownership. La documentación y un plan de rollback siempre.

¿Cuándo usar Riesgo de Seguridad: Acceso No y cuándo una alternativa?

Esta solución es ideal para el caso descrito. Alternativas como Docker, Ansible o configuración manual pueden ser mejores según contexto: portabilidad, escala y reproducibilidad son los factores clave.

¿Cómo migro desde una configuración previa a Riesgo de Seguridad: Acceso No?

Documentar el estado actual, probar la nueva configuración en staging, validar funcionalmente, y aplicar en producción con rollback plan listo. Los posts de SoyLinux incluyen troubleshooting para los problemas más comunes.

Lee también

Alfonso Moreno | Sysadmin Senior

Soy Alfonso, sysadmin senior con RHCE y más de 10 años administrando sistemas Linux para empresas y proyectos personales. Me especializo en infraestructura, redes, virtualización, monitoring, automation y self-hosting. Sobre SoyLinux.com SoyLinux.com es un blog técnico en español sobre Linux, software libre y self-hosting. Lo mantengo en mi tiempo libre. Áreas de expertise - Linux server administration: RHEL, CentOS, Rocky, Alma, Fedora, Debian, Ubuntu - Network services: Postfix, BIND, Samba, NFS, Squid - Virtualización y containers: KVM, Proxmox, Docker, Podman - Monitoring: Prometheus, Grafana, Zabbix - Automation: Ansible, Bash scripting - Self-hosting: Vaultwarden, Nextcloud, Jellyfin, Immich, Homelab Contacto - Email: [email protected]

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *