Ataques a la cadena de suministro ahora apuntan a la confianza

El próximo ataque a la cadena de suministro no llegará como una dependencia obviamente maliciosa. Llegará por algo que tu pipeline ya confía — una attestation de provenance firmada desde un build comprometido, un token de CI extraído de la memoria del runner, o un preinstall hook idéntico a la versión limpia de ayer.

Ingeniería9 min de lectura
CiberseguridadCadena de suministroCI/CDDevSecOpsDependencias
Compartir

Más de 454,000 paquetes maliciosos nuevos fueron identificados en npm, PyPI, Maven Central y NuGet solo en 2025 — llevando el total acumulado más allá de 1.2 millones de artefactos conocidos de malware en la cadena de suministro. Pero el número esconde el cambio más importante: los ataques supply chain modernos ya no dependen de que los desarrolladores instalen un paquete obviamente incorrecto. Comprometen los sistemas que los equipos ya confían — build pipelines, tokens OIDC, attestations de provenance, cuentas de maintainers — y publican código malicioso a través de canales que se ven exactamente como un release normal.

El modelo de amenaza cambió. Escanear dependencias por vulnerabilidades conocidas sigue importando, pero aborda la generación anterior de ataques. La generación actual falsifica las señales de confianza en las que el escaneo se apoya. Un paquete con provenance SLSA Build Level 3 válido, publicado desde el repositorio oficial por las credenciales del maintainer oficial, pasando todos los checks de CI — ese paquete puede ser malicioso. La superficie de ataque ya no es el árbol de dependencias. Es la infraestructura que produce y certifica el árbol de dependencias.

La cadena de suministro es ahora el entorno de ejecución

Los ataques supply chain evolucionaron de envenenamiento pasivo — publicar un paquete con typosquatting y esperar a que alguien lo instale — a explotación activa de la infraestructura de build. Los gusanos auto-replicantes descubiertos en 2025 y 2026 se mueven a través de pipelines de CI/CD de forma autónoma, robando credenciales y propagándose a paquetes adicionales sin intervención humana.

El patrón de ataque: comprometer una cuenta de maintainer (frecuentemente por reutilización de credenciales o phishing), inyectar un preinstall hook en un paquete popular, y usar ese hook para extraer secrets del CI runner que ejecuta npm install. Los tokens robados — tokens de publicación de npm, tokens OIDC de GitHub Actions, credenciales de AWS, tokens de service accounts de Kubernetes — se convierten en el medio para comprometer el siguiente paquete, que compromete el siguiente proyecto, que expone el siguiente conjunto de credenciales.

Esto no es una cadena teórica. En mayo de 2026, paquetes de visualización comprometidos dispararon impacto cascada en downstream hacia librerías con más de un millón de descargas semanales. El payload extrajo memoria de proceso de los runners de GitHub Actions, exfiltró credenciales multi-plataforma, y usó tokens de npm robados para publicar paquetes comprometidos adicionales — todo dentro del contexto de ejecución legítimo del CI/CD.

Las señales de confianza pueden ser secuestradas — incluyendo provenance firmado

SLSA (Supply-chain Levels for Software Artifacts) fue diseñado para resolver exactamente este problema: probar que un paquete fue construido desde un commit específico, en un builder específico, sin manipulación. Pero provenance solo prueba origen. No prueba que el origen fue seguro.

En mayo de 2026, atacantes explotaron misconfiguraciones de pull_request_target en GitHub Actions para secuestrar pipelines de release y publicar docenas de paquetes con attestations válidas de SLSA Build Level 3. La provenance era genuina — el build corrió en la plataforma esperada, desde el repositorio esperado, firmado por la identidad esperada. El pipeline en sí fue el componente comprometido. Cada señal de confianza verificó correctamente porque el ataque operó dentro de los límites del sistema confiado.

Esto rompe el modelo mental que la mayoría de equipos carga: "si los checks de provenance pasan, el artefacto es seguro." Provenance prueba que el artefacto vino de un pipeline específico. No prueba que el pipeline no estaba comprometido antes de que el artefacto fuera producido. La respuesta de verificación es "sí, esto fue construido aquí" — pero la pregunta que los equipos realmente necesitan responder es "¿era confiable este entorno de build en el momento en que construyó este artefacto?"

Los tokens de CI son credenciales de producción de alto valor

Un runner de GitHub Actions con permisos contents: write y packages: write puede publicar paquetes, pushear a repositorios y modificar artefactos de release. Un runner con id-token: write puede emitir tokens OIDC aceptados por cloud providers. Estos no son conveniencias de desarrollo. Son credenciales de producción almacenadas en el almacén de secrets más grande que la mayoría de organizaciones mantienen — el sistema de CI en sí.

Las prioridades de hardening:

  • Principio de mínimo privilegio en permisos de workflow. Default permissions: {} a nivel de workflow. Otorgar contents: read o id-token: write solo a jobs específicos que lo requieran. Nunca usar permissions: write-all fuera de workflows de release explícitamente auditados.
  • Pinear actions a SHAs de commit inmutables, no tags. Los tags pueden ser force-pushed para apuntar a commits diferentes. Un SHA es inmutable. uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 sobrevive manipulación de tags; uses: actions/checkout@v4 no.
  • Separar build y publish en jobs distintos. El job que compila código no necesita credenciales de publicación. El job que publica debería tener acceso de solo lectura a outputs de build y acceso de solo escritura al registry — nada más.
  • Usar pull_request en vez de pull_request_target a menos que el workflow explícitamente necesite acceso a secrets para PRs de forks. El trigger pull_request_target corre en el contexto del branch base con acceso completo a secrets — un archivo de workflow mal configurado convierte cada fork PR en un vector potencial de exfiltración de credenciales.
  • Restringir audience y claims del token OIDC. Delimitar tokens OIDC al mínimo set de recursos cloud y condiciones. Un token que autentica a * en AWS no es una credencial temporal — es una llave maestra con fecha de expiración.

Las dependencias transitivas convierten la exposición en un problema de grafos

Las dependencias directas son auditables. Las dependencias transitivas — los paquetes de los que dependen tus paquetes — forman un grafo que ningún humano revisa en su totalidad. Un solo patch release comprometido cinco capas abajo se propaga a miles de proyectos durante la ventana entre publicación y detección.

Las mitigaciones prácticas:

  • Lockear dependencias a hashes exactos, no version ranges. Un package-lock.json o bun.lockb pineado a hashes de integridad específicos significa que un patch release comprometido no entra silenciosamente al build hasta que alguien explícitamente actualice el lockfile y revise el diff.
  • Desabilitar lifecycle scripts por defecto en CI. Usar --ignore-scripts durante la instalación. Allow-list solo los paquetes específicos cuyos postinstall hooks son requeridos (compilación nativa, por ejemplo). La vasta mayoría de paquetes legítimos no necesitan ejecutar código durante la instalación.
  • Monitorear mutaciones de dependencias. Un patch release que no cambia código fuente pero agrega un script preinstall es una señal. Un release publicado desde una IP o región geográfica diferente al patrón histórico del maintainer es una señal. Las herramientas que detectan estas anomalías a nivel de registry existen — la pregunta es si los equipos las integran antes o después del incidente.
  • Mantener un inventario de cada paquete con acceso transitivo a secrets de CI. Si un paquete corre durante npm install en un job que tiene permisos id-token: write, ese paquete tiene acceso indirecto al token OIDC. El radio de explosión efectivo no es el árbol de dependencias — es la intersección del árbol de dependencias y el grafo de permisos.

La ventana entre compromiso y detección es la variable crítica. En los incidentes de mayo 2026, patch releases comprometidos estuvieron activos durante horas a días antes de que los registries los removieran. Cada proyecto que corrió npm install durante esa ventana ejecutó el payload. Los proyectos usando lockfiles pineados a la versión anterior no fueron afectados — la versión comprometida nunca entró en su build hasta que un humano revisó la actualización. Los lockfiles no son una optimización de performance. Son una frontera de seguridad que convierte un compromiso supply chain zero-day en un diff revisable.

¿Qué deberían asegurar primero los equipos contra ataques supply chain?

La prioridad depende del radio de explosión de un compromiso. Empezar con los targets de mayor valor: credenciales de publicación y permisos de tokens de CI/CD.

¿Cuál es el primer paso para hardear CI/CD contra compromiso supply chain?

Auditar cada archivo de workflow por permisos excesivos. Default todos los workflows a permissions: {} y otorgar permisos específicos solo a jobs que los necesiten. Eliminar triggers pull_request_target a menos que sean esenciales y hayan sido revisados por un ingeniero de seguridad. Pinear todas las actions de terceros a SHAs de commit. Esta sola pasada elimina el punto de entrada más común para ataques a nivel de pipeline sin requerir tooling nuevo.

¿La provenance SLSA protege contra ataques supply chain?

La provenance SLSA prueba que un artefacto fue construido por un builder específico desde una fuente específica. No prueba que el entorno de build no estaba comprometido al momento del build. Provenance es una capa necesaria — elimina clases de manipulación que ocurren después del build. Pero no es suficiente cuando el ataque ocurre dentro del build pipeline en sí. Tratar provenance como una señal en un stack de verificación multi-capa, no como una decisión binaria de confianza.

¿Deberían los equipos bloquear paquetes sin attestations de provenance?

Bloquear paquetes sin attestations es una política defendible para deployments de producción — pero el ecosistema aún no está ahí. La mayoría de paquetes en npm y PyPI no publican provenance SLSA. Un paso intermedio práctico: requerir attestations para dependencias directas, monitorear dependencias transitivas por anomalías, y gatear solo el pipeline de deployment (no cada install de desarrollo) con verificación de provenance.

Una visión opuesta

Un argumento común sostiene que las herramientas de escaneo de dependencias — Snyk, Socket, Dependabot, npm audit — atrapan la vasta mayoría de amenazas supply chain antes de que lleguen a producción. Para equipos sin capacidad dedicada de ingeniería de seguridad, invertir en hardening de pipeline y verificación de provenance es una distracción de prácticas de mayor impacto como habilitar MFA en cuentas de maintainers, mantener dependencias actualizadas, y correr escaneos básicos de vulnerabilidades.

Esta visión es correcta sobre prioridad relativa para equipos pequeños. Un equipo sin escaneo alguno debería agregar escaneo antes de preocuparse por attestations SLSA. Pero la generación actual de ataques específicamente apunta al gap entre lo que los scanners detectan y lo que el build pipeline confía. Un paquete comprometido publicado por una cuenta legítima, sin CVE conocido, y con provenance válido — ese paquete pasa todos los scanners. La postura defensiva que depende exclusivamente del escaneo es la postura que los ataques actuales están diseñados para evadir.

Lo que importa recordar

  • Los ataques supply chain modernos apuntan a sistemas de confianza — tokens de CI, attestations de provenance, cuentas de maintainers — no solo dependencias.
  • Provenance prueba origen. No prueba seguridad. Un paquete con attestations SLSA válidas puede ser malicioso si el build pipeline estaba comprometido.
  • Los runners de CI con permisos amplios son credenciales de producción. Default todos los permisos de workflow a vacío y otorgar acceso por job.
  • Pinear actions a SHAs de commit, desabilitar lifecycle scripts en CI, y lockear dependencias a hashes exactos — estos tres controles eliminan los vectores de propagación más comunes.
  • Las dependencias transitivas intersectadas con grafos de permisos de CI definen el radio de explosión real. Auditar esa intersección, no solo el árbol de dependencias.
  • Los scanners de dependencias atrapan amenazas conocidas. La generación actual de ataques está diseñada para evadirlos operando dentro de límites confiados.

Conclusión

El modelo de amenaza de la cadena de suministro cambió de "alguien podría instalar un paquete malo" a "alguien podría publicar un paquete malo a través de un sistema que la organización ya confía." Las defensas que funcionaban contra typosquatting y vulnerabilidades conocidas — escaneo, actualización, higiene básica — son necesarias pero ya no suficientes. La siguiente capa requiere tratar la infraestructura de CI/CD como un perímetro de seguridad, tratar cada token como un path potencial de movimiento lateral, y aceptar que provenance es una señal, no una garantía. El ataque que llega a través de un paquete firmado, attestado, verificado por CI, desde una cuenta de maintainer que era legítima ayer — ese es el ataque que el tooling actual no atrapa por defecto, y para el que todo equipo de producción necesita un plan de respuesta.

Artículos relacionados

Paleta de comandos

Buscá un comando para ejecutar...