Volver a la sala de prensa
Amenazas

Alpine Linux reconstruye su GitLab tras un ataque contra la falla de Ruby con CVSS 10.0

Un atacante pasó dos días bombardeando el GitLab autoalojado de Alpine Linux con configuraciones de CI diseñadas para CVE-2026-97229. El proyecto no halló pruebas de que el exploit funcionara, pero reconstruyó el servidor de todos modos y descubrió que actualizar GitLab por sí solo deja intacto el fallo de Ruby.

Alpine Linux reconstruye su GitLab tras un ataque contra la falla de Ruby con CVSS 10.0

Alpine Linux reconstruye su GitLab tras un ataque contra la falla de Ruby con CVSS 10.0

Alpine Linux reconstruyó desde cero su servidor GitLab autoalojado y restableció la contraseña de todos los usuarios después de que un atacante pasara dos días intentando explotar CVE-2026-97229, una vulnerabilidad de ejecución remota de código con severidad máxima, contra la instancia que aloja las fuentes de los paquetes de la distribución. El proyecto hizo público el incidente el 28 de octubre.

Qué ocurrió

CVE-2026-97229 tiene una puntuación CVSS de 10.0. La debilidad no está en el código de GitLab, sino en Onigmo, el motor de expresiones regulares integrado en Ruby. GitLab compila con Ruby las expresiones regulares de las configuraciones de CI, de modo que un patrón manipulado en un archivo .gitlab-ci.yml puede llegar al motor vulnerable y, bajo ciertas condiciones, ejecutar código en el servidor. GitLab publicó la corrección el 12 de octubre parcheando el Ruby incluido en sus paquetes Linux y en sus imágenes oficiales de contenedor. Al día siguiente ya circulaba públicamente un exploit funcional de prueba de concepto.

El servidor de Alpine es el que aloja aports, el repositorio a partir del cual se construyen todos los paquetes de la distribución. El 13 de octubre el proyecto lo actualizó a GitLab 19.3.4 en lugar de 19.3.5, algo que el equipo reconoce como un error: 19.3.4 figuraba inicialmente como la versión corregida para la rama 19.3, pero el aviso de seguridad se modificó más tarde para listarla como afectada.

El 20 de octubre, una cuenta recién registrada empezó a sondear el servidor. Durante el 20 y el 21 de octubre envió configuraciones de CI manipuladas que hicieron caer los procesos worker de GitLab ocho veces, provocaron errores 502 e hicieron fallar trabajos de CI. En cuatro de esas caídas el atacante avanzó parte de la cadena de explotación antes de fallar en el siguiente paso. La misma cuenta descargó además la imagen pública de contenedor GitLab de Alpine, lo que el proyecto interpreta como un intento de ajustar el exploit a su build exacto.

Alpine bloqueó la cuenta el 23 de octubre. El atacante regresó el 25 y el 26 de octubre e intentó volver a entrar, sin éxito.

Por qué actualizar GitLab no bastó

El 22 de octubre Alpine pasó el servidor a GitLab 19.3.6 y dio el problema por resuelto. El 26 de octubre descubrió que la instancia seguía siendo vulnerable. La razón es sencilla una vez que se ve: la corrección de GitLab está en el Ruby que GitLab incluye dentro de sus propios paquetes e imágenes. La imagen de contenedor de Alpine instala por separado un Ruby estándar, así que la actualización de GitLab nunca tocó el motor de expresiones regulares vulnerable.

La misma brecha afecta a cualquier instalación de GitLab compilada manualmente o a cualquier imagen personalizada que traiga su propio Ruby. Esos servidores necesitan Ruby 3.3.13, 3.4.12 o 4.0.9 (o posterior), además de una versión corregida de GitLab. Ruby 3.2 llegó al final de su vida útil en abril y no recibirá la corrección; sin embargo, la guía de instalación compilada de GitLab todavía lista 3.2 como versión mínima, y ninguno de los anuncios de parches de GitLab de octubre indica a los administradores de instalaciones compiladas que actualicen Ruby.

El 27 de octubre Alpine cerró GitLab a todos salvo a sus desarrolladores y servidores de compilación, e inició la reconstrucción. El nuevo servidor quedó listo el 28 de octubre con Ruby 3.3.13 o posterior, nuevas claves secretas de GitLab y un restablecimiento obligatorio de contraseña para cada cuenta. Se está probando antes de reabrirlo al público.

Lo que Alpine puede y no puede descartar

El proyecto no encontró indicios de que el código del atacante llegara a ejecutarse: las pruebas de temporización no mostraron retrasos, no hubo archivos, claves, hooks ni procesos inesperados, y ningún dato privado salió a través de ninguna petición web o de API que Alpine pueda ver.

Eso no equivale a una prueba de seguridad. Un exploit exitoso de esta falla no deja caídas ni rastro en los registros web. Algunos registros de los días del ataque se han perdido, incluidos los de los trabajos en segundo plano y el sistema de archivos del contenedor antiguo, y ni Alpine ni su proveedor de alojamiento registraban las conexiones de red salientes. Como la evidencia necesaria para confirmar o descartar la ejecución de código ya no existe, Alpine optó por tratar el servidor como comprometido y reconstruirlo.

Si el ataque hubiera tenido éxito, los datos expuestos podrían haber incluido nombres, direcciones de correo e IP de los usuarios, hashes de contraseñas, secretos de doble factor, variables de CI/CD, tokens de runner, credenciales de webhooks y de push mirror, tokens de acceso personal (almacenados como hash), repositorios privados e issues y merge requests confidenciales. Más allá del restablecimiento de contraseñas y las nuevas claves secretas, Alpine aún no ha dicho si los tokens de runner, las variables de CI/CD, los tokens de acceso o las credenciales de integración almacenadas en el servidor han sido rotados.

Los paquetes parecen limpios

La mayor preocupación para el ecosistema es la manipulación de la cadena de suministro, y aquí las noticias son mejores. Alpine verificó que cada cambio en aports recibido entre el 20 y el 22 de octubre llegó mediante un push registrado de un desarrollador conocido, y lo contrastó con registros fuera del alcance del atacante: la copia local del repositorio de un desarrollador y los 45 servidores de compilación. Todos los paquetes construidos del 20 al 24 de octubre, y las publicaciones del 21 de octubre, incluidos los archivos minirootfs con los que se construyen las imágenes oficiales de Alpine para Docker, coinciden con esos cambios verificados. Las comprobaciones se están extendiendo hasta el 27 de octubre, el día en que se cerró el servidor. Las claves que firman los paquetes y las publicaciones de Alpine nunca han estado en el servidor GitLab.

Qué servidores GitLab están expuestos

GitLab.com y GitLab Dedicated ya están parcheados. Para servidores autogestionados, las versiones corregidas son 19.4.2, 19.3.5 y 19.2.8, y las publicaciones del 21 de octubre (19.5.1, 19.4.3, 19.3.6, 19.2.9, 19.1.9, 19.0.10 y 18.11.13) son las más recientes de cada rama; también cierran CVE-2026-110264, una falla de expresiones regulares distinta. Las ramas 19.5, 19.1, 19.0 y 18.11 no figuran como afectadas.

La prueba de concepto pública necesita primero acceso de escritura: el atacante sube un archivo de CI malicioso y una ruta de archivo con caracteres UTF-8 a una rama de un proyecto público, tras lo cual solo la petición final de CI lint queda sin autenticar. Esa barrera desaparece en servidores donde los usuarios nuevos pueden registrarse por sí mismos y crear proyectos. Aún no se sabe cómo el informe original enviado a GitLab, todavía privado, evita el paso de escritura, y Alpine no ha explicado cómo llegaron al servidor las configuraciones de CI de su atacante. El CVE no estaba en el catálogo de vulnerabilidades explotadas conocidas de CISA a fecha de 28 de octubre.

Qué hacer

  • Paquete Linux o imagen oficial de contenedor: actualice a la versión más reciente de su rama.
  • Instalación compilada o imagen personalizada con su propio Ruby: actualice GitLab y pase Ruby a 3.3.13, 3.4.12, 4.0.9 o posterior. Los servidores que sigan en 19.3.4 deben pasar a 19.3.6.
  • Si no puede actualizar de inmediato: restrinja el acceso anónimo a proyectos públicos, impida que usuarios no confiables creen o escriban en proyectos públicos, o bloquee la ruta de CI lint. Estas medidas solo cubren la vía de explotación conocida y no corrigen el motor en sí.
  • Busque señales de explotación: GitLab ha publicado seis reglas de detección en formato Sigma que cubren patrones hostiles en las advertencias de regexp de CI y en peticiones GraphQL ciLint, rutas de archivo inusualmente largas con caracteres no ASCII e informes de fallo de Ruby que apuntan a Onigmo. Revise también archivos propiedad del usuario git en /tmp, procesos hijo inesperados de Puma o Sidekiq, conexiones salientes y cambios en crontabs o claves SSH. Cualquier indicio de ejecución implica tratar el servidor como comprometido y rotar gitlab-secrets.json, todas las variables de CI/CD, los tokens de runner y los tokens de acceso.
  • Reduzca la superficie de ataque: limite quién puede crear cuentas y tokens de acceso personal.
  • Usuarios de Alpine: establezcan una contraseña nueva mediante "Forgot your password?" cuando el servidor reabra y cámbienla en cualquier otro sitio donde la hayan reutilizado; Alpine ha detectado intentos de credential stuffing con contraseñas filtradas de otros sitios. Quienes usen la imagen alpinelinux/gitlab deben volver a descargar la etiqueta 19.3.6, ya que solo la imagen publicada el 27 de octubre incluye Ruby 3.3.13. Los paquetes de Ruby de Alpine ya están corregidos (3.4.12 en Alpine 3.22, 3.23, 3.24 y edge; 3.3.13 en 3.21) y apk upgrade los instala.

Los mantenedores de Ruby señalan que el fallo solo afecta a programas que compilan una expresión regular a partir de texto controlado por un atacante, y que el ajuste Regexp.timeout no ofrece protección.

La lección que Alpine aprendió por las malas es que actualizar una aplicación no dice nada sobre el runtime que tiene debajo. Una simple comprobación de la versión de GitLab expuesta habría pasado; solo una prueba del comportamiento real, o un inventario que incluya el build de Ruby, lo habría detectado. Esa distancia entre "parcheado sobre el papel" y "parcheado en la práctica" es precisamente lo que nuestro servicio de escaneo de vulnerabilidades está diseñado para sacar a la luz en su infraestructura expuesta a internet, antes de que lo haga el archivo de CI manipulado de otra persona.

COMPARTIR