- केवल
git push path की internal protocol flaw से backend में remote code execution संभव था; GitHub.com पर इसे पहले ही mitigate किया जा चुका है, लेकिन GHES पर patch लागू करना ज़रूरी है
- user-controlled input push option सीधे
X-Stat header में चला जाता था, जिससे एक semicolon के ज़रिए नया field inject किया जा सकता था, और same key के बाद वाले value द्वारा पहले वाले को overwrite करने वाले last-write-wins व्यवहार का दुरुपयोग हुआ
- inject किए जा सकने वाले fields में
rails_env, custom_hooks_dir, repo_pre_receive_hooks को मिलाकर sandbox को bypass किया जा सकता था और attacker द्वारा बताए गए path के hooks को git user permissions के साथ चलाया जा सकता था
- इसी mechanism से GitHub.com का enterprise mode flag भी inject किया गया, जिससे shared storage node पर code execution की पुष्टि हुई और उस node पर मौजूद दूसरे users और organizations के repositories तक read access संभव हो गया
- यह दिखाता है कि multi-service architecture में, जहाँ अलग-अलग services shared format पर भरोसा करती हैं, input sanitization की कमी, non-production execution path, और path validation की अनुपस्थिति मिलकर गंभीर vulnerability बना सकती हैं
तत्काल प्रतिक्रिया और प्रभाव का दायरा
- GitHub.com पर यह issue पहले ही mitigate किया जा चुका है और कोई अतिरिक्त कार्रवाई आवश्यक नहीं है
- GitHub Enterprise Server पर तत्काल कार्रवाई आवश्यक है, और
CVE-2026-3854 fix शामिल करने वाले GHES 3.19.3 या उससे ऊपर में upgrade करना चाहिए
- vulnerable version range GHES 3.19.1 और उससे नीचे है, जबकि fixed versions के रूप में
3.14.24, 3.15.19, 3.16.15, 3.17.12, 3.18.6, 3.19.3 दिए गए हैं
- लिखे जाने के समय तक GHES instances का 88% अभी भी vulnerable था
- GitHub की अतिरिक्त technical information और recovery procedures GitHub Security Blog पर देखी जा सकती हैं
- Wiz ग्राहक Wiz Threat Center की prebuilt query से vulnerable GHES instances की पहचान कर सकते हैं
जांच की पृष्ठभूमि और approach
- GitHub का internal git infrastructure वह path है जो सभी
git push requests को handle करता है, और इसमें कई internal services हैं जो अलग-अलग programming languages में लिखी गई हैं
- ऐसे multi-service structure में, shared data को parse और trust करने के तरीके में components के बीच का अंतर vulnerability बन सकता है
- पहले इस pipeline को बनाने वाले बड़े पैमाने के compiled black-box binaries को extract और audit करने में अत्यधिक समय और manual effort लगता था
- AI-augmented tools और
IDA MCP आधारित automated reverse engineering की मदद से compiled binaries का तेज़ी से analysis कर internal protocol को reconstruct किया जा सका
- इस प्रक्रिया में user input pipeline के पूरे flow में server behavior को कहाँ प्रभावित करता है, इसका systematic tracing किया गया और input flow की मौलिक खामी खोजी गई
internal architecture और trust boundaries
- जब
git push SSH के जरिए आता है, तो request का flow babeld, gitauth, gitrpcd, और फिर pre-receive hook तक जाता है
babeld सभी git operations का entry point है, जो SSH connection स्वीकार करता है, और authentication को gitauth को forward करता है
gitauth user credentials और repository push permissions की पुष्टि करता है, और file size limit या branch name rules जैसी security policies लौटाता है
babeld इसी response के आधार पर security metadata वाला internal X-Stat header बनाता है
gitrpcd X-Stat header प्राप्त कर आगे की process environment सेट करता है, और बिना किसी अपने authentication के babeld पर पूरी तरह भरोसा करता है
- pre-receive hook push स्वीकार होने से पहले file size limits, branch name rules, LFS integrity, और admin-defined custom hooks की जाँच करता है
- मुख्य कड़ी X-Stat header थी, जिसमें
; से अलग किए गए key=value pairs होते थे
- internal services
X-Stat को ; के आधार पर split करके map में भरती थीं, और यदि same key दो बार आए तो बाद वाला value पहले वाले को overwrite कर देता था; यही last-write-wins नियम था
babeld git push -o से आए push options को push_option_0, push_option_1, push_option_count जैसे fields के रूप में X-Stat में साथ जोड़ देता था
vulnerability का कारण: X-Stat field injection
babeld user-controlled input यानी push option value को X-Stat header में copy करते समय semicolon को sanitize नहीं करता था
- क्योंकि
; ही X-Stat field separator था, इसलिए push option के अंदर एक semicolon मूल field से बाहर निकलकर नया attacker-controlled field बना सकता था
- उदाहरण के लिए,
push_option_0 के अंदर large_blob_rejection_enabled=bool:false inject करने पर पहले से सेट bool:true को बाद वाला value overwrite कर देता था
- यह व्यवहार binary analysis और वास्तविक GHES instance की packet capture दोनों में पुष्टि हुआ
- reverse engineering और wire-level analysis को मिलाकर inject किए जा सकने वाले
X-Stat fields की mapping की गई
- विशेष रूप से security-sensitive fields के रूप में
rails_env, custom_hooks_dir, repo_pre_receive_hooks, large_blob_rejection_enabled, reject_sha_like_refs, user_operator_mode की पहचान हुई
- इनमें
rails_env, custom_hooks_dir, repo_pre_receive_hooks ये तीन fields remote code execution तक ले जाने वाली मुख्य कड़ी थे
GHES में RCE तक पहुँचने का path
- GHES push स्वीकार होने से पहले चलने वाले custom pre-receive hooks को support करता है
- pre-receive binary में
X-Stat के rails_env value के आधार पर बँटे हुए दो execution paths थे
- यदि value
production हो, तो hook sandbox के अंदर चलता था; अन्य किसी value पर वह बिना sandbox या isolation के सीधे git service user permissions के साथ execute होता था
- इसलिए
rails_env को non-production value में inject करने से sandbox bypass संभव हो गया
- इसके बाद
custom_hooks_dir inject करने से hook scripts खोजने वाली base directory attacker के नियंत्रण में आ जाती थी
- अंत में
repo_pre_receive_hooks में path traversal वाला hook definition inject करने पर binary का path resolution attacker-controlled directory और traversal payload को जोड़कर filesystem के arbitrary path की ओर इशारा करने लगा
- non-production execution path इस तरह resolve हुए path को बिना arguments, बिना sandbox, और
git service user के रूप में सीधे execute करता था
- वास्तविक validation में एक ही
git push से uid=500(git) output लौटा, जिससे git user permissions के साथ RCE की पुष्टि हुई
- इस permission के साथ GHES instance के filesystem पर read-write access और internal service configuration visibility समेत पूर्ण नियंत्रण हासिल किया जा सकता था
GitHub.com तक विस्तार और cross-tenant exposure
- जब यही exploit chain GitHub.com repository पर लागू की गई, तो शुरुआत में push सफल हुआ लेकिन custom hooks execute नहीं हुए
user_operator_mode=bool:true inject कर दोनों platforms के debug output की तुलना करने पर पता चला कि GitHub.com पर custom hooks code path तक पहुँचा ही नहीं जा रहा था
- आगे की reverse engineering से यह सामने आया कि server का enterprise mode व्यवहार नियंत्रित करने वाला boolean flag
X-Stat header में मौजूद था
- GHES में यह flag default रूप से true था, इसलिए custom hooks path हमेशा enabled रहता था; GitHub.com में default false होने से सामान्य स्थिति में वह path reachable नहीं था
- क्योंकि यह flag भी उसी mechanism से inject किया जा सकता था, एक अतिरिक्त field inject कर GitHub.com पर भी पूरी exploit chain काम करने लगी
- इसके बाद GitHub.com infrastructure के भीतर
hostname execution result लौटाया गया, जिससे GitHub.com RCE की पुष्टि हुई
- GitHub.com एक multi-tenant platform है, जहाँ कई users और organizations के repositories shared backend infrastructure पर stored होते हैं
- जहाँ code execution हुआ वह shared storage node था, और वहाँ
git user के पास उस node के सभी repository operations को process करने के लिए व्यापक filesystem permissions थीं
- यदि यह user compromise हो जाए, तो उस node पर मौजूद दूसरे organizations और users के repositories भी ownership की परवाह किए बिना पढ़े जा सकते हैं
- compromise हुए दो nodes पर accessible repository index entries enumerate करने पर हर node में millions of entries मिले, जिनमें अन्य users और organizations के repositories शामिल थे
- अन्य tenants के repositories की वास्तविक contents तक पहुँच नहीं की गई; केवल अपने test accounts का उपयोग करके यह verify किया गया कि
git user की filesystem permissions node के भीतर सभी repositories को पढ़ने की अनुमति देती हैं
मुख्य सबक और disclosure timeline
- केवल एक
git push से internal protocol flaw का दुरुपयोग कर backend infrastructure पर remote code execution संभव था
- जब अलग-अलग languages में लिखी कई services shared internal protocol के माध्यम से data exchange करती हैं, तो हर service की trust assumptions स्वयं attack surface बन जाती हैं
- इस chain में एक service ने push option values को जस का तस insert किया, दूसरी service ने
X-Stat के सभी fields पर भरोसा किया, और pre-receive hook ने मान लिया कि production environment में rails_env हमेशा production ही होगा
- production binaries के भीतर मौजूद non-production code paths, hook scripts में path traversal validation की कमी, और delimiter-based protocol में input sanitization की अनुपस्थिति ऐसे patterns हैं जो दूसरे codebases में भी मिल सकते हैं
- multi-service architectures चलाने वाली teams को खास तौर पर यह जाँचना चाहिए कि जब security-sensitive settings shared data format से derive होती हों, तब user-controlled input internal protocol के भीतर कैसे flow करता है
- इस research में
IDA MCP सहित AI-augmented reverse engineering tools ने compiled binaries के analysis और internal protocol reconstruction को तेज़ बनाया
- जैसे-जैसे ऐसे tools mature होंगे, वे उन vulnerability classes को खोजने में और महत्वपूर्ण भूमिका निभाएँगे जिनमें गहरा cross-component analysis चाहिए होता है
- disclosure timeline के अनुसार
2026-03-04 को X-Stat push option injection vulnerability खोजी गई, उसी दिन GHES 3.19.1 पर RCE की पुष्टि कर GitHub को report किया गया, और GitHub.com fix भी उसी दिन deploy हुआ
2026-03-10 को CVE-2026-3854 और CVSS 8.7 assign किए गए, और GHES patch जारी हुआ
2026-04-28 को public disclosure हुआ
अभी कोई टिप्पणी नहीं है.