Proteger Astro de ataques a la cadena de… | LaunchFast
LaunchFast Logo LaunchFast
Blog
2188 palabras 11 min de lectura

Proteger Astro de ataques a la cadena de suministro: Parte 1 - Entender Shai-Hulud 2.0 y respuesta inmediata

Conozca el ataque a la cadena de suministro de npm Shai-Hulud 2.0, que comprometió más de 700 paquetes. Descubra cómo comprobar si su proyecto Astro está afectado y tome medidas inmediatas para asegurar su entorno.

Rishi Raj Jain
Rishi Raj Jain Autor
Proteger Astro de ataques a la cadena de suministro Parte 1

Esta es la Parte 1 de una serie de dos artículos sobre cómo proteger sitios Astro de ataques a la cadena de suministro de npm. En este artículo cubriremos la comprensión de la amenaza y las acciones de respuesta inmediata. Consulte la Parte 2 para medidas de seguridad a largo plazo, monitorización y mejores prácticas.

Sponsored

Kits de inicio de alta calidad con flujo de autenticación integrada (Auth.js), carga de objetos (AWS, Clouflare R2, Firebase Storage, Supabase Storage), pagos integrados (Stripe, LemonSqueezy), flujo de verificación de correo electrónico (Resend, Postmark, Sendgrid) y mucho más . Compatible con cualquier base de datos (Redis, Postgres, MongoDB, SQLite, Firestore).

Get all 3 kits Bundle ↗

One-time license · Lifetime updates

En noviembre de 2025, el ecosistema npm enfrentó uno de los ataques a la cadena de suministro más significativos hasta la fecha: Shai-Hulud 2.0. Este ataque comprometió más de 700 paquetes npm, incluidas bibliotecas populares de Zapier, PostHog y Postman, afectando aproximadamente al 27 % de los entornos de nube y código. El malware se ejecutó durante la fase preinstall, robando credenciales de GitHub, AWS, GCP, Azure y otros servicios, y luego las exfiltró a repositorios públicos.

Según Wiz Research, se crearon más de 25.000 repositorios maliciosos que contenían secretos robados, con nuevos repositorios apareciendo a un ritmo de ~1.000 cada 30 minutos durante el ataque. Si ejecuta un sitio Astro, esta guía le ayudará a entender la amenaza y tomar medidas inmediatas.

Requisitos previos

Necesitará lo siguiente:

  • Node.js 20 o posterior
  • Un proyecto Astro existente
  • Acceso a la configuración de su pipeline CI/CD
  • Acceso administrativo a su gestor de paquetes (npm, pnpm o yarn)

1. Entender el ataque Shai-Hulud 2.0

El ataque Shai-Hulud 2.0 aprovechó cuentas de mantenedores comprometidas para publicar versiones troyanizadas de paquetes npm legítimos. No se trató de una nueva vulnerabilidad zero-day ni de un exploit sofisticado: fue una compromisión de cuentas de confianza que permitió a los atacantes publicar código malicioso bajo la apariencia de actualizaciones legítimas.

1.1 ¿Qué hace diferente a este ataque?

A diferencia de los ataques tradicionales, esta variante introdujo varias características preocupantes:

1.1.1 Se ejecuta durante la fase preinstall

El malware se ejecuta durante el hook del ciclo de vida preinstall, lo que amplía drásticamente el radio de impacto. Esto significa:

  • Se ejecuta antes de que se complete cualquier instalación de paquetes
  • Se ejecuta en las máquinas de los desarrolladores durante npm install
  • Se ejecuta automáticamente en los pipelines CI/CD
  • No puede evitarse fácilmente con medidas de seguridad habituales
// Ejemplo de cómo se veía el package.json malicioso
{
"scripts": {
"preinstall": "node malicious-script.js"
}
}

1.1.2 Roba múltiples tipos de credenciales

El ataque no se limitó a un solo tipo de credencial. Buscó activamente y exfiltró:

  • Tokens de GitHub: tokens de acceso personal, tokens OAuth y deploy keys
  • Credenciales de AWS: claves de acceso a largo plazo (formato AKIA), secret keys y session tokens
  • Credenciales de GCP: claves de cuentas de servicio y credenciales de aplicación
  • Credenciales de Azure: credenciales de service principal y claves de almacenamiento
  • Variables de entorno: cualquier secreto almacenado en archivos .env o en el entorno

1.1.3 Utiliza exfiltración entre víctimas

Uno de los aspectos más insidiosos es que sus datos robados podrían no aparecer siquiera en su propia cuenta de GitHub:

// Ejemplo simplificado de la lógica de exfiltración
const victims = getRandomVictimAccounts()
const stolenData = gatherCredentials()
// Subir a la cuenta de OTRA víctima
uploadToGitHub(victims[randomIndex], stolenData)

Esto significa:

  • Sus secretos podrían estar en el repositorio público de otra persona
  • Los secretos de otras víctimas podrían aparecer en su cuenta
  • La detección es significativamente más difícil
  • El radio de impacto es mucho mayor de lo que inicialmente parece

1.1.4 Crea workflows de puerta trasera

El malware intentó inyectar workflows maliciosos de GitHub Actions para acceso persistente:

# Ejemplo de .github/workflows/discussion.yaml inyectado
name: Discussion Update
on:
push:
schedule:
- cron: '0 */6 * * *'
jobs:
exfiltrate:
runs-on: ubuntu-latest
steps:
- name: Gather More Secrets
run: |
# Código malicioso aquí

1.1.5 Afecta a paquetes de alta prevalencia

El ataque se dirigió a paquetes ampliamente utilizados en el ecosistema:

  • @postman/tunnel-agent - Encontrado en el 27 % de los entornos
  • posthog-node - Encontrado en el 25 % de los entornos
  • @asyncapi/specs - Encontrado en el 20 % de los entornos
  • Varios paquetes de la plataforma Zapier

Esto maximizó el alcance del ataque, afectando potencialmente a miles de proyectos al instante.

1.2 Cronología del ataque e impacto

Esto es lo que sabemos sobre la progresión del ataque:

  • 21-23 de noviembre de 2025: Compromiso inicial y carga de paquetes troyanizados en npm

  • 24 de noviembre de 2025 (01:22 UTC): Primera evidencia de repositorios creados en GitHub con secretos filtrados

  • 24 de noviembre de 2025 (~03:00 UTC): Primera evidencia de versiones maliciosas de paquetes en npm

  • 25 de noviembre de 2025 (22:45 UTC): Posible segunda fase observada con publicación de repositorios privados

  • 26 de noviembre de 2025: GitHub comienza la mitigación revocando tokens y privatizando repositorios maliciosos

Estadísticas de impacto:

  • ~700 paquetes comprometidos en npm
  • Más de 25.000 repositorios maliciosos creados
  • ~500 usuarios de GitHub afectados
  • Más de 775 tokens de acceso de GitHub comprometidos (verificados)
  • Más de 373 credenciales de AWS filtradas
  • Más de 300 credenciales de GCP expuestas
  • Más de 115 credenciales de Azure comprometidas

El malware crea archivos indicadores específicos:

Terminal window
cloud.json # Credenciales de proveedores cloud
contents.json # Contenido del repositorio y código
environment.json # Variables de entorno y secretos
truffleSecrets.json # Secretos detectados por patrones de TruffleHog
bun_environment.js # Datos del entorno de ejecución de Bun
setup_bun.js # Script de configuración para persistencia

2. Acciones inmediatas a tomar

Si sospecha que su proyecto Astro podría estar afectado, siga estos pasos de inmediato. El tiempo es crítico: cuanto más tiempo permanezcan activas las credenciales comprometidas, mayor será el daño.

2.1 Comprobar sus dependencias

Primero, verifique si alguno de los paquetes comprometidos está en su árbol de dependencias.

2.1.1 Comprobación rápida con pnpm audit

Terminal window
# Ejecutar una auditoría de seguridad
pnpm audit fix
# O con npm
npm audit --audit-level=moderate

2.1.2 Inspección manual

Revise su package.json y los archivos lock en busca de paquetes de alto riesgo:

Terminal window
# Comprobar paquetes comprometidos específicos
grep -E "@postman/tunnel-agent|posthog-node|posthog-js|@asyncapi/specs|zapier-platform" package.json pnpm-lock.yaml

2.1.3 Paquetes comprometidos conocidos (lista parcial)

Estos son algunos de los paquetes afectados más prevalentes:

{
"high-prevalence-packages": [
"@postman/tunnel-agent",
"posthog-node",
"posthog-js",
"@asyncapi/specs",
"@asyncapi/openapi-schema-parser",
"zapier-platform-cli",
"zapier-platform-core",
"zapier-platform-schema",
"zapier-async-storage",
"get-them-args",
"shell-exec",
"kill-port"
]
}

2.1.4 Comprobar dependencias transitivas

Los paquetes comprometidos podrían no ser dependencias directas. Compruebe todo su árbol de dependencias:

Terminal window
# Para pnpm
pnpm list --depth=Infinity | grep -E "postman|posthog|zapier"
# Para npm
npm list --all | grep -E "postman|posthog|zapier"

2.1.5 Revisar el historial de instalación

Compruebe cuándo se instalaron los paquetes por última vez para determinar la ventana de exposición:

Terminal window
# Comprobar el historial git de cambios en el archivo lock
git log -p --follow pnpm-lock.yaml | grep -A 5 -B 5 "postman\|posthog\|zapier"

2.2 Auditar su entorno

Busque evidencia de compromiso en su entorno de desarrollo local y en los sistemas CI/CD.

2.2.1 Escanear archivos maliciosos

Terminal window
# Buscar archivos indicadores de malware conocidos
find . -type f \( \
-name "cloud.json" -o \
-name "contents.json" -o \
-name "environment.json" -o \
-name "truffleSecrets.json" -o \
-name "bun_environment.js" -o \
-name "setup_bun.js" \
\) 2>/dev/null

Si este comando devuelve algún resultado, su entorno ha sido comprometido.

2.2.2 Comprobar workflows de GitHub

Terminal window
# Listar todos los archivos de workflow
ls -la .github/workflows/
# Comprobar el workflow malicioso conocido
cat .github/workflows/discussion.yaml 2>/dev/null

El workflow malicioso suele tener:

  • Nombre: “Discussion Update” o similar
  • Programaciones cron sospechosas
  • Acceso inusual a variables de entorno
  • Comandos codificados en Base64

2.2.3 Revisar el historial de Git en busca de cambios no autorizados

Terminal window
# Comprobar commits recientes en busca de cambios sospechosos
git log --all --oneline --decorate --graph -n 20
# Buscar adiciones inesperadas de workflows
git log --all --full-history -- .github/workflows/

2.2.4 Comprobar sus repositorios de GitHub

Inicie sesión en GitHub y compruebe:

  • Repositorios públicos inesperados en su cuenta
  • Repositorios con nombres que contengan datos o credenciales filtradas
  • Descripciones de repositorios que mencionen “Shai-Hulud” o contenido sospechoso
  • Repositorios recién creados que usted no creó

2.2.5 Verificar los logs de CI/CD

Revise los logs de su pipeline CI/CD en busca de:

  • Conexiones de red inesperadas durante las compilaciones
  • Intentos de autenticación fallidos
  • Instalaciones de paquetes inusuales
  • Aumentos en la duración de las compilaciones (la ejecución del malware lleva tiempo)
Terminal window
# Ejemplo: comprobar logs de GitHub Actions
gh run list --limit 20
gh run view <run-id> --log

2.3 Rotar todas las credenciales

Si ha identificado paquetes comprometidos o archivos sospechosos, rote inmediatamente todas las credenciales. No espere a confirmar el alcance completo del compromiso.

2.3.1 Tokens de GitHub

  1. Vaya a GitHub Settings → Developer settings → Personal access tokens
  2. Revise todos los tokens existentes:
    • Anote para qué se utiliza cada token
    • Compruebe la fecha de último uso
  3. Revocar TODOS los tokens (incluso si parecen seguros)
  4. Cree nuevos tokens con los permisos mínimos necesarios:
Terminal window
# Use el principio de mínimo privilegio
# En lugar de:
# - repo (control total)
# Use:
# - repo:status (solo lectura)
# - public_repo (si es posible)
  1. Actualice los tokens en:
    • Secretos de CI/CD (GitHub Actions, CircleCI, etc.)
    • Entornos de desarrollo local
    • Cualquier script de automatización
    • Integraciones de terceros

2.3.2 Credenciales de AWS

Rote las claves de acceso de AWS de inmediato:

Terminal window
# 1. Listar las claves de acceso actuales
aws iam list-access-keys --user-name your-username
# 2. Crear nuevas claves de acceso PRIMERO
aws iam create-access-key --user-name your-username
# Guarde la salida inmediatamente: no la volverá a ver
# 3. Actualice las nuevas claves donde se utilicen:
# - Secretos de CI/CD
# - ~/.aws/credentials
# - Variables de entorno
# - Configuración de la aplicación
# 4. Compruebe que las nuevas claves funcionan
aws sts get-caller-identity
# 5. Elimine las claves de acceso antiguas
aws iam delete-access-key \
--access-key-id AKIA_OLD_KEY_ID \
--user-name your-username

2.3.3 Pasos importantes de seguridad en AWS

Terminal window
# Comprobar CloudTrail en busca de actividad no autorizada
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=Username,AttributeValue=your-username \
--max-items 100 \
--start-time 2025-11-20T00:00:00Z
# Revisar el acceso reciente a buckets S3
aws s3api get-bucket-logging --bucket your-bucket-name
# Comprobar cambios no autorizados en IAM
aws iam get-credential-report

2.3.4 Credenciales de GCP

Para Google Cloud Platform:

Terminal window
# Listar cuentas de servicio
gcloud iam service-accounts list
# Crear una nueva clave para una cuenta de servicio
gcloud iam service-accounts keys create new-key.json \
--iam-account=sa-name@project-id.iam.gserviceaccount.com
# Listar todas las claves de una cuenta de servicio
gcloud iam service-accounts keys list \
--iam-account=sa-name@project-id.iam.gserviceaccount.com
# Eliminar claves antiguas
gcloud iam service-accounts keys delete KEY_ID \
--iam-account=sa-name@project-id.iam.gserviceaccount.com

2.3.5 Credenciales de Azure

Para Microsoft Azure:

Terminal window
# Listar service principals
az ad sp list --show-mine
# Restablecer credenciales del service principal
az ad sp credential reset \
--id <app-id> \
--append
# Crear un nuevo client secret
az ad sp credential reset \
--id <app-id> \
--credential-description "New secret after Shai-Hulud"

2.3.6 Credenciales de base de datos

No olvide rotar las credenciales de la base de datos:

Terminal window
# Ejemplo para PostgreSQL
# Conéctese a su base de datos
psql -U admin -d postgres
# Cree un nuevo usuario con los mismos privilegios
CREATE USER newuser WITH PASSWORD 'strong-new-password';
GRANT ALL PRIVILEGES ON DATABASE yourdb TO newuser;
# Actualice la configuración de la aplicación
# Pruebe a fondo
# Luego elimine el usuario antiguo
DROP USER olduser;

2.3.7 Variables de entorno y secretos

Actualice todos los secretos del entorno:

scripts/rotate-env-secrets.ts
import crypto from 'crypto'
const generateSecureSecret = (length: number = 32): string => {
return crypto.randomBytes(length).toString('hex')
}
console.log('🔐 New secrets generated:\n')
console.log(`SESSION_SECRET=${generateSecureSecret(64)}`)
console.log(`API_SECRET=${generateSecureSecret(32)}`)
console.log(`ENCRYPTION_KEY=${generateSecureSecret(32)}`)
console.log(`JWT_SECRET=${generateSecureSecret(64)}`)
console.log('\n⚠️ Update these in:')
console.log(' - Vercel/Netlify/hosting platform')
console.log(' - GitHub repository secrets')
console.log(' - Local .env files')
console.log(' - Team password manager')

Próximos pasos

Ha tomado los primeros pasos críticos para asegurar su proyecto Astro. Sin embargo, protegerse de ataques a la cadena de suministro requiere vigilancia continua y prácticas de seguridad sólidas.

En la Parte 2, exploramos la prevención a largo plazo (bloqueo de dependencias, comprobaciones de integridad, endurecimiento de CI/CD), aislamiento de dependencias, gestión de secretos, escaneos automatizados y monitorización.

Conclusión

El ataque Shai-Hulud 2.0 es un recordatorio contundente de que la seguridad de la cadena de suministro no es opcional: es un componente crítico del desarrollo web moderno. Las acciones inmediatas cubiertas en este artículo son solo la primera línea de defensa.

Si tiene preguntas o comentarios, no dude en contactarme en Twitter.

Sigue leyendo