Durante años, los programas de seguridad de aplicaciones se han centrado en los entornos de producción: endurecer servidores, parchear vulnerabilidades, desplegar WAFs y monitorizar el comportamiento en tiempo de ejecución. Ese enfoque tenía sentido cuando la mayoría de los compromisos relevantes ocurrían después del despliegue, explotando debilidades en las aplicaciones en ejecución.
Pero los atacantes modernos eluden cada vez más las defensas de producción. En lugar de atacar la aplicación en tiempo de ejecución, comprometen los sistemas que compilan, empaquetan y entregan el software: los pipelines CI/CD y la cadena de suministro de software que hay detrás de ellos.
En muchas organizaciones, los pipelines CI/CD son hoy un objetivo más valioso y más frágil que la propia producción. La razón es sencilla: los pipelines se sitúan en la intersección de la confianza, los privilegios y la distribución. Si los atacantes pueden controlar el pipeline, pueden controlar lo que llega a producción y lo que llega a los usuarios.
Este artículo explica por qué los pipelines se convirtieron en una superficie de ataque principal, qué nos enseñan los incidentes recientes de la cadena de suministro, en qué se diferencia la seguridad del pipeline de la seguridad en tiempo de ejecución y qué errores de diseño comunes mantienen a los pipelines vulnerables. La conclusión es clara: el pipeline es una frontera de confianza, y debe diseñarse como tal.
La evolución de los ataques al software
Las amenazas clásicas de seguridad de aplicaciones apuntaban a vulnerabilidades en tiempo de ejecución: inyección SQL, RCE, SSRF, bypass de autenticación y escalada de privilegios. Los defensores han pasado dos décadas elevando el coste de estos ataques mediante:
- Mejoras en el parcheo, el escaneo de dependencias y la gestión de vulnerabilidades
- Controles de seguridad cloud-native e infraestructura gestionada
- Mejor aislamiento (contenedores, sandboxes, segmentación)
- Capacidades centralizadas de registro y detección
Como resultado, los adversarios se adaptaron. Si la producción se vuelve más difícil de explotar directamente, los atacantes buscan apalancamiento en otro lugar, y el proceso de entrega de software ofrece ese apalancamiento.
En lugar de preguntarse «¿Cómo entro en este sistema en ejecución?», los atacantes se preguntan cada vez más:
¿Cómo consigo que mi código se envíe como si fuera legítimo?
Cuando eso ocurre, las defensas diseñadas para el compromiso en tiempo de ejecución pueden volverse irrelevantes. Una actualización maliciosa entregada a través de canales legítimos no es una «brecha» en el sentido tradicional: puede parecer un funcionamiento normal.
Tres incidentes que ilustran el cambio
Los incidentes de la cadena de suministro de gran repercusión no ocurrieron porque las defensas en tiempo de ejecución fueran débiles. Ocurrieron porque los atacantes comprometieron mecanismos de entrega que se sitúan aguas arriba de la producción. Los detalles difieren, pero el patrón es consistente: compromete un paso de build o distribución de confianza y heredarás la confianza a escala.
SolarWinds: compromete el build y llega a todos
En el incidente de SolarWinds, los atacantes lograron inyectar código malicioso en las actualizaciones de software. La característica definitoria no fue un único servidor explotado, sino la capacidad de distribuir software con puerta trasera a través de un canal de actualización de confianza.
El retorno de la inversión del atacante fue enorme: compromete el pipeline de build o de release una sola vez y luego deja que los clientes instalen tu payload por ti.
Codecov: compromete el tooling de CI y roba secretos a escala
En el incidente de Codecov, un compromiso afectó a cómo los entornos de CI manejaban un script. El impacto práctico: los sistemas de CI que se ejecutaban en muchas organizaciones filtraron información sensible.
Los entornos de CI son extremadamente sensibles porque suelen albergar:
- Tokens de repositorio
- Credenciales de nube
- Claves de firma o acceso a servicios de firma
- Secretos de despliegue
Este incidente pone de relieve que el tooling de CI no es «solo automatización»: es un sistema de procesamiento de secretos de alto valor.
3CX: compromete a un proveedor y convierte la confianza en un arma
El incidente de 3CX demostró otra dinámica de la cadena de suministro: comprometer a un proveedor y convertir la confianza en un arma para distribuir software malicioso a los clientes posteriores.
Desde el punto de vista de la defensa, la lección no se limita a los proveedores. Internamente, tu pipeline CI/CD es, en la práctica, un «proveedor» de tu entorno de producción y de tus usuarios: producción confía en las salidas del pipeline.
Por qué el pipeline es más atractivo que la producción
Los atacantes eligen sus objetivos en función del apalancamiento. Los pipelines CI/CD ofrecen un apalancamiento que los sistemas de producción rara vez igualan.
1) Los pipelines agregan confianza
Un pipeline es el tejido conectivo entre:
- Repositorios de código fuente (Git)
- Registros de dependencias (npm, PyPI, Maven, etc.)
- Sistemas de build y runners
- Repositorios de artefactos (registros de contenedores, repos de paquetes)
- Sistemas de firma y metadatos de procedencia
- Destinos de despliegue (Kubernetes, cuentas de nube, servidores de producción)
Comprometer la producción normalmente te da acceso a un entorno. Comprometer el pipeline puede darte:
- Acceso a múltiples entornos mediante credenciales de automatización
- Control sobre los artefactos de release
- Influencia sobre qué se despliega y cuándo
Los pipelines son «multiplicadores de confianza»: pueden tomar entradas no confiables y producir salidas de confianza. Si los atacantes controlan esa transformación, controlan la confianza.
2) Los pipelines operan con privilegios elevados por diseño
La automatización necesita privilegios. Los pipelines a menudo requieren permisos para:
- Leer y escribir en repositorios (incluidas etiquetas y releases)
- Descargar dependencias y publicar artefactos
- Acceder a secretos para la firma o el despliegue
- Desplegar en staging o producción
En muchas organizaciones, las identidades del pipeline se convierten en «superidentidades» con el tiempo, porque es más fácil conceder acceso amplio que diseñar permisos granulares.
Esto crea una estrategia de ataque predecible: comprometer la identidad del pipeline en lugar de luchar contra las defensas de producción.
3) El compromiso del pipeline escala mejor
El compromiso en tiempo de ejecución a menudo escala mal: hay que explotar los objetivos de forma repetida, manejar la variabilidad entre entornos y mantener la persistencia por cada objetivo.
El compromiso del pipeline escala de forma eficiente: inyecta una vez, distribuye por todas partes. Si puedes modificar un paso de build, una ruta de resolución de dependencias o un artefacto de release, puedes comprometer muchos sistemas mientras pareces legítimo.
4) La detección es más difícil porque «todo parece normal»
Las herramientas de seguridad de producción buscan comportamientos sospechosos en tiempo de ejecución: llamadas de red inesperadas, escaladas de privilegios, procesos anómalos. Pero si el código malicioso se envía como un release normal, se ejecuta como parte del comportamiento esperado de la aplicación.
Sin controles de integridad y procedencia sólidos, los defensores pueden tener dificultades para responder:
¿Es este binario/contenedor realmente lo que pretendíamos compilar?
Seguridad del pipeline frente a seguridad en tiempo de ejecución
Un error común es pensar que la seguridad del pipeline es simplemente «seguridad en tiempo de ejecución más temprano en el ciclo de vida». Ese planteamiento es incompleto. La seguridad del pipeline y la seguridad en tiempo de ejecución protegen garantías diferentes.
La seguridad en tiempo de ejecución responde:
¿Qué está haciendo este sistema ahora mismo y es malicioso?
La seguridad del pipeline responde:
¿Por qué deberíamos confiar en este software en absoluto?
Si el pipeline está comprometido, las defensas en tiempo de ejecución podrían proteger fielmente una aplicación maliciosa, porque desde la perspectiva del sistema es «la aplicación». El verdadero fallo ocurrió aguas arriba, en el punto donde se estableció la confianza.
Por eso la seguridad de la cadena de suministro se centra en:
- La integridad de las salidas del build
- La procedencia (quién/qué lo construyó, dónde y cómo)
- Las puertas de verificación antes del despliegue
- Reducir la capacidad de manipular los pasos de build y de release
Dónde son realmente vulnerables los pipelines
Para asegurar los pipelines, debemos ser específicos sobre dónde ocurren los ataques. «CI/CD» no es un único componente. Es una cadena de componentes y transiciones de confianza. Estos son los puntos atacables más comunes.
Fuente: pull requests y contribuciones no confiables
Muchos pipelines ejecutan código procedente de pull requests. Si el pipeline trata el código de un PR como confiable (o filtra secretos a los builds de PR), los atacantes pueden exfiltrar credenciales o modificar las salidas del build.
Dependencias: confianza transitiva a escala de internet
Los builds modernos incorporan cientos o miles de dependencias de terceros. Una dependencia comprometida, un paquete de typosquatting o la dependency confusion pueden desplazar la ejecución dentro del entorno de build, a menudo sin tocar tu código fuente.
Configuración del pipeline: «código» que a menudo se revisa menos
Las definiciones de CI (workflows YAML, plantillas compartidas, actions reutilizables) controlan la ejecución. Un cambio sutil puede:
- Ampliar permisos
- Introducir exfiltración de datos
- Cambiar las fuentes de artefactos
- Deshabilitar comprobaciones de seguridad
Sin embargo, la configuración de CI a veces recibe una revisión menos rigurosa que el código de aplicación.
Runners: el entorno de ejecución es una frontera de seguridad
Los runners alojados, los runners autoalojados y los contenedores efímeros tienen perfiles de riesgo diferentes. Pero el punto clave es universal: los runners ejecutan entradas no confiables. Si los runners no están aislados correctamente, se convierten en el punto de apoyo de un atacante.
Artefactos: la integridad y la procedencia a menudo se asumen, no se demuestran
Muchas organizaciones dan por sentado que «si viene de CI, es seguro». Esa es precisamente la suposición que los atacantes explotan. Sin firmas, atestaciones y puertas de verificación, la integridad de los artefactos es frágil.
Errores de diseño comunes en los pipelines
La mayoría de los compromisos de pipeline tienen éxito debido a errores de ingeniería predecibles, normalmente motivados por la velocidad, la comodidad o una propiedad poco clara. Estos errores crean violaciones de confianza silenciosas.
Error n.º 1: tratar los runners de CI como «internos y de confianza»
Los runners a menudo se ejecutan dentro de redes de confianza y tienen acceso a recursos sensibles. Pero ejecutan código que puede estar influido por colaboradores externos, dependencias o actions de terceros. Si el runner se ve comprometido, el atacante puede:
- Robar secretos de las variables de entorno
- Extraer tokens de la configuración local
- Modificar las salidas del build
- Persistir a través de cachés, imágenes o volúmenes compartidos
Error n.º 2: identidades de pipeline con privilegios excesivos
Los tokens amplios (por ejemplo, tokens de repositorio «write-all», credenciales de nube multientorno) son habituales. Facilitan la automatización, pero también dan a los atacantes una vía rápida hacia el impacto.
Error n.º 3: fronteras débiles entre las etapas del pipeline
Si una etapa temprana puede influir en los artefactos usados por etapas posteriores sin verificación de integridad, el envenenamiento de artefactos se vuelve trivial. Esto incluye:
- Cachés de build sin verificar
- Espacios de trabajo compartidos entre jobs
- Artefactos pasados entre etapas sin comprobaciones
Error n.º 4: componentes de terceros sin controlar
Las actions, plugins y plantillas reutilizables son potentes. Pero también añaden riesgo de cadena de suministro dentro del propio CI. Si los componentes de terceros no se fijan, revisan y restringen, se convierten en un vector de ejecución.
Error n.º 5: «comprobaciones de seguridad» que no controlan el despliegue
El escaneo de seguridad que no bloquea los releases a menudo se considera «suficientemente bueno». Desde la perspectiva de un atacante, es irrelevante. Los controles deben ser aplicables: deben afectar a lo que puede compilarse, firmarse y desplegarse.
El pipeline es una frontera de confianza
El modelo mental correcto no es «CI/CD como automatización». Es CI/CD como frontera de confianza.
Una frontera de confianza es donde las entradas no confiables se convierten en salidas de confianza. Eso es exactamente lo que hace un pipeline:
- Toma código fuente (potencialmente influido por muchos actores)
- Resuelve dependencias (a menudo de ecosistemas externos)
- Ejecuta las instrucciones de build
- Produce artefactos en los que producción confiará
Si no haces explícita la confianza, obtienes confianza implícita. La confianza implícita es lo que los atacantes monetizan.
Diseñar el pipeline como una frontera de confianza significa:
- Fronteras de etapa explícitas con aislamiento y verificación entre ellas
- Mínimo privilegio para las identidades del pipeline, por job y por entorno
- Ejecución efímera (o aislamiento fuerte) para los runners y los builds
- Integridad criptográfica para los artefactos (firma y verificación)
- Procedencia y atestaciones que puedan validarse en el momento del despliegue
Qué debería incluir una estrategia de seguridad moderna
Si los pipelines son superficies de ataque principales, los programas de seguridad deben invertir en consecuencia. No añadiendo más «comprobaciones», sino incorporando garantías sólidas al proceso de entrega.
1) Modela las amenazas del pipeline (no solo de la aplicación)
Mapea las fronteras de confianza: entradas de PR, resolución de dependencias, runners, almacenamiento de artefactos, firma y despliegue. Identifica dónde puede entrar la influencia no confiable.
2) Reduce el privilegio y el alcance de forma agresiva
Usa identidades delimitadas por job, credenciales delimitadas por entorno, tokens de corta vida y fronteras de permisos explícitas. Evita los «superusuarios del pipeline».
3) Endurece los runners y los entornos de ejecución
Prefiere los runners efímeros siempre que sea posible. Si usas runners autoalojados, aíslalos: restricciones de red, controles del sistema de archivos, sin estado compartido de larga vida y una segregación estricta entre las cargas de trabajo no confiables y las de confianza.
4) Haz que la integridad sea verificable, no asumida
Firma los artefactos, genera atestaciones y verifícalas antes del despliegue. Asegúrate de que producción confíe en la verificación, no meramente en el hecho de que «lo produjo CI».
5) Valida los cambios del pipeline como cambios de producción
Trata la configuración de CI como código de alto riesgo. Usa code owners, revisiones y aplicación de políticas para evitar la ampliación silenciosa de privilegios o la inyección de pasos no confiables.
Conclusión
Los pipelines CI/CD se han convertido silenciosamente en algunos de los componentes más críticos —y más explotados— de los ecosistemas de software modernos. Agregan confianza, operan con privilegios elevados y proporcionan a los atacantes una vía de gran apalancamiento hacia el impacto a escala.
El paso más importante es cambiar el modelo mental:
Un pipeline CI/CD no es «solo automatización». Es una frontera de confianza.
Las organizaciones que diseñen sus pipelines con fronteras de confianza explícitas —mediante aislamiento, mínimo privilegio, integridad y procedencia— estarán en una posición mucho mejor para defenderse de la próxima generación de ataques a la cadena de suministro de software.