
Reproduzierbares Labor für CVE-2026-10053 (GitLab npm-Paket-Registry-Pfad-Traversal -> beliebiges Dateischreiben als git). Verwundbare Version 19.2.1 im Vergleich zu gepatchter 19.2.2, deterministisches Orakel.
In sich geschlossenes Labor, das die Pfad-Traversal-Schwachstelle im npm-Paket-Registry von GitLab beweist (CVE-2026-10053) und zeigt, dass sie behoben ist, mithilfe eines deterministischen On-Disk-Orakels – nicht HTTP-Status.
Was bewiesen ist und was nicht. Dieses Labor beweist authentifiziertes beliebiges Dateischreiben als der
git-Betriebssystem-Benutzer auf verwundbarem GitLab und dass das gepatchte Release es blockiert. Es ist kein eigenständiger Remote-Code-Execution-PoC – siehe Scope. Zitieren Sie es nicht als RCE.
| Schwachstelle | CWE-22 Pfad-Traversal im npm-Paket-Registry (TOCTOU: Prüfung lief before :cache, nicht before :store) |
| CVSS | 8.5 Hoch — AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:H/A:H |
| Betroffen | GitLab CE/EE 18.8 → <19.0.6, 19.1 → <19.1.4, 19.2 → <19.2.2 |
| Behoben | 19.0.6 / 19.1.4 / 19.2.2 — Commit 435cf863 "Upload-Pfad-Traversal vor dem Speichern erneut validieren" |
python3, git, curl auf dem Host../run.sh # up + provision + exploit + verify BOTH; exits 0 iff vuln writes AND patched blocks
Erwartetes Ergebnis:
================ CVE-2026-10053 verification ================
INSTANCE EXPECT RESULT STATUS
gitlab-vuln (19.2.1) written written PASS
gitlab-patched (19.2.2) blocked blocked PASS
------------------------------------------------------------
PROVEN: authenticated arbitrary file write as git on 19.2.1.
NOT a standalone RCE — see README.md 'Scope' and ./run.sh rce-gate.
============================================================
Weitere Unterbefehle:
./run.sh up # just start + wait until healthy
./run.sh rce-gate # honest exec-bit-gate demo (below)
./run.sh down # docker compose down -v
Sowohl der verwundbare als auch der gepatchte Server antworten auf die bösartige Veröffentlichung mit
HTTP 200 {"status":"processing"} – die Datei wird später im Finalize-Worker geschrieben. HTTP-Status ist
also kein Orakel. exploit/poc.py --verify-docker <container> fragt stattdessen innerhalb des
Containers nach der kontrollierten Datei am traversierten Pfad und vergleicht deren SHA-1:
/var/tmp/CVE_2026_10053_PROOF-1.0.0.tgz erscheint (Besitzer git:git, unsere Bytes) → Exit 0.Gitlab::PathTraversal::PathTraversalAttackError: Invalid path → Exit 2.Der Exploit selbst ist nichts anderes als die authentifizierte PUT …/packages/npm/:pkg-Anforderung; die Traversal
befindet sich vollständig im JSON-Body name (file_name = "#{name}-#{version}.tgz", nur auf Leerheit geprüft).
Die docker exec-Aufrufe sind Verifikation und Einrichtung, niemals Teil der Fähigkeiten des Angreifers.
git-beschreibbaren Pfad. Dateien landen mit 0644.-<semver>.tgz zu enden (NUL wird
vom Kernel abgelehnt, Zeilenumbruch kürzt nicht), daher kann kein exakt benanntes Ziel (secrets.yml, authorized_keys,
eine .rb, Gitaly-Binärdateien) überschrieben werden. Der einzige dateinamenunabhängige Ausführungsmechanismus,
custom_hooks/<hook>.d/, führt jeden Dateinamen aus, aber nur wenn ausführbar – und dieser Schreibvorgang ist 0644.
Das Überschreiben einer vorhandenen 0755-Datei hilft nicht: Der Store ersetzt den Inode und setzt ihn
auf 0644 zurück. RCE benötigt also eine separate Executable-Bit-/Ausführungsprimitive, die dieser PoC nicht liefert../run.sh rce-gate demonstriert genau dies ehrlich: Es platziert einen pre-receive.d-Hook über die
Traversal, pusht und zeigt, dass der 0644-Hook nicht ausgeführt wird. ./rce_gate_demo.sh --illustrate-gate
setzt zusätzlich +x über docker exec chmod (eine Out-of-Band-Docker-Root-Aktion, keine Angreiferfähigkeit), nur
um zu zeigen, dass Gitaly ihn ausführen würde – was unterstreicht, dass der fehlende Hebel das Exec-Bit ist.
Siehe ANALYSIS.md für die vollständige Analyse. Kurz gesagt: app/uploaders/gitlab_uploader.rb
validierte den Speicherpfad nur before :cache; bei before :store wurde der modellabgeleitete file_name
(angreiferkontrolliert, unvalidiert) wörtlich geschrieben. Der Fix fügt before :store, :protect_from_path_traversal! hinzu.
docker-compose.yml vuln (19.2.1) + patched (19.2.2) GitLab CE
run.sh one-command harness with deterministic file oracle + PASS/FAIL
provision.rb lab setup: mint root PAT + create project (NOT part of the exploit)
exploit/poc.py the PoC sender + --verify-docker oracle
rce_gate_demo.sh honest exec-bit-gate demonstration