- केवल
git pushpath की internal protocol flaw से backend में remote code execution संभव था; GitHub.com पर इसे पहले ही mitigate किया जा चुका है, लेकिन GHES पर patch लागू करना ज़रूरी है - user-controlled input push option सीधे
X-Statheader में चला जाता था, जिससे एक 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 कोgituser 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-3854fix शामिल करने वाले 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 pushrequests को 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 pushSSH के जरिए आता है, तो request का flowbabeld,gitauth,gitrpcd, और फिर pre-receive hook तक जाता है babeldसभी git operations का entry point है, जो SSH connection स्वीकार करता है, और authentication कोgitauthको forward करता हैgitauthuser credentials और repository push permissions की पुष्टि करता है, और file size limit या branch name rules जैसी security policies लौटाता हैbabeldइसी response के आधार पर security metadata वाला internalX-Statheader बनाता हैgitrpcdX-Statheader प्राप्त कर आगे की process environment सेट करता है, और बिना किसी अपने authentication केbabeldपर पूरी तरह भरोसा करता है- pre-receive hook push स्वीकार होने से पहले file size limits, branch name rules, LFS integrity, और admin-defined custom hooks की जाँच करता है
- मुख्य कड़ी X-Stat header थी, जिसमें
;से अलग किए गएkey=valuepairs होते थे - internal services
X-Statको;के आधार पर split करके map में भरती थीं, और यदि same key दो बार आए तो बाद वाला value पहले वाले को overwrite कर देता था; यही last-write-wins नियम था babeldgit push -oसे आए push options कोpush_option_0,push_option_1,push_option_countजैसे fields के रूप मेंX-Statमें साथ जोड़ देता था
vulnerability का कारण: X-Stat field injection
babelduser-controlled input यानी push option value कोX-Statheader में copy करते समय semicolon को sanitize नहीं करता था- क्योंकि
;हीX-Statfield separator था, इसलिए push option के अंदर एक semicolon मूल field से बाहर निकलकर नया attacker-controlled field बना सकता था - उदाहरण के लिए,
push_option_0के अंदरlarge_blob_rejection_enabled=bool:falseinject करने पर पहले से सेटbool:trueको बाद वाला value overwrite कर देता था - यह व्यवहार binary analysis और वास्तविक GHES instance की packet capture दोनों में पुष्टि हुआ
- reverse engineering और wire-level analysis को मिलाकर inject किए जा सकने वाले
X-Statfields की 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_envvalue के आधार पर बँटे हुए दो execution paths थे - यदि value
productionहो, तो hook sandbox के अंदर चलता था; अन्य किसी value पर वह बिना sandbox या isolation के सीधेgitservice user permissions के साथ execute होता था - इसलिए
rails_envको non-production value में inject करने से sandbox bypass संभव हो गया - इसके बाद
custom_hooks_dirinject करने से 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, और
gitservice user के रूप में सीधे execute करता था - वास्तविक validation में एक ही
git pushसेuid=500(git)output लौटा, जिससेgituser 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:trueinject कर दोनों platforms के debug output की तुलना करने पर पता चला कि GitHub.com पर custom hooks code path तक पहुँचा ही नहीं जा रहा था- आगे की reverse engineering से यह सामने आया कि server का enterprise mode व्यवहार नियंत्रित करने वाला boolean flag
X-Statheader में मौजूद था - 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 के भीतर
hostnameexecution result लौटाया गया, जिससे GitHub.com RCE की पुष्टि हुई - GitHub.com एक multi-tenant platform है, जहाँ कई users और organizations के repositories shared backend infrastructure पर stored होते हैं
- जहाँ code execution हुआ वह shared storage node था, और वहाँ
gituser के पास उस 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 किया गया कि
gituser की 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.7assign किए गए, और GHES patch जारी हुआ2026-04-28को public disclosure हुआ
1 टिप्पणियां
Hacker News की राय
बात ऐसी बन गई कि अंदरूनी authentication service जो security-critical headers सेट करती है, उसमें
अंतिम उपयोगकर्ता द्वारा
git push -oसे डाली गई मनमानी string भी शामिल हो गईबाद में कहना आसान है, लेकिन फिर भी यह बहुत ही बेतुकी गलती लगती है
AI-augmented reversing तरीका इस समय LLM agents की ताकत को अच्छी तरह दिखाता है
code पर खूब trained models जटिल systems के अंदरूनी हिस्सों को समझने की गति बहुत बढ़ा सकते हैं
security research में आम तौर पर 1) जटिल internal behavior को समझना और 2) उसके भीतर vulnerabilities ढूँढना, ये दोनों काम एक-दूसरे पर चढ़े होते हैं,
और कई बार असली internal mechanism सामने आते ही vulnerability खुद उम्मीद से कहीं आसान दिखने लगती है
CVE-2026-3854 ऐसा मामला नहीं था कि अंदरूनी चीज़ें जानते ही तुरंत obvious लगे,
लेकिन अगर यह ज़्यादा पारंपरिक या आसान attack surface पर exposed होता, तो यह command injection शायद बहुत जल्दी मिल जाता
लेकिन आजकल लगता है कि वह रुझान थोड़ा बिखर गया है, या फिर C++ syntax की जटिलता से बनने वाले dev/vendor lock-in को बचाने वालों की वजह से जानबूझकर रुकावट डाली जा रही है
लगता है मानो Wiz में सचमुच काम करने वाले लोग हों, क्योंकि नतीजा काफ़ी अच्छा दिखता है
product ने बेहद तेज़ growth और feature bloat के बावजूद अभी तक काफ़ी अच्छी तरह टिके रहना जारी रखा है,
और security team भी अक्सर सचमुच दिलचस्प चीज़ें ढूँढ निकालती है
osv-scannerऔरtrivyचलाने वाली custom pipeline ही इस्तेमाल करते हैंजबकि CLI से DC query करना और credentials reset करना जैसे कुछ ज़्यादा संदिग्ध कामों पर चुप रहता है, जो काफ़ी निराशाजनक है
जब
babeldpush request को आगे भेजता है, तो वह internal request के X-Stat header में push options डाल देता है,और वह value वही मनमानी string होती है जो उपयोगकर्ता
git push -oसे देता हैलेकिन semicolon को sanitize किए बिना value को ज्यों का त्यों कॉपी कर दिया गया,
और क्योंकि
;X-Stat field separator है, हमलावर original field से बाहर निकलकर नया field बना सकता हैयह सचमुच सबसे बुनियादी तरह की गलती है, मानो low-hanging fruit इतना नीचे लटका हो कि ज़मीन के अंदर धँस गया हो
यह vulnerability वास्तविक exploitation से पहले ही पकड़ ली गई,
फिर भी BREAKING, unauthorized access, millions of repositories जैसी भाषा से बेवजह डर बढ़ाने की ज़रूरत है क्या, ऐसा लगता है
https://x.com/wiz_io/status/2049153209982140718
GitHub की किस्मत अच्छी थी कि उसे कोई nation-state attacker नहीं बल्कि Wiz की fuzzing ने पकड़ा
88% GHES instances ने 7 हफ़्ते पहले आए critical security patch को अब तक लागू नहीं किया है, यह काफ़ी गंभीर लगता है
https://docs.github.com/en/enterprise-server@3.19/admin/release-notes#3.19.3
patch-level release लागू करने में भी कई घंटे का downtime चाहिए होता है,
और कोई supported HA upgrade तरीका भी नहीं है, इसलिए ईमानदार customers के लिए भी तुरंत latest version तक पहुँचना मुश्किल है
शिकायत करो तो सब GitHub Enterprise Cloud पर चले जाने को कहते हैं,
लेकिन आज के माहौल में कितने लोग उसे तुरंत चुनेंगे, यह भी सवाल है
हाँ, GHES का एक फ़ायदा यह है कि github.com की रोज़मर्रा की outages के दौरान यह बंद नहीं होता
और शायद वे ऐसा दिन चुनना चाहते हैं जब operational impact कम हो ताकि upgrade किया जा सके
लेकिन अगर यह public instance है, तो तुरंत update करना चाहिए
article में दी गई जानकारी और public GitHub Enterprise source भर से reproduction method निकालना मुश्किल नहीं लगता
या फिर schedule के अनुसार चलते रहो और उम्मीद करो कि कुछ न हो — आम तौर पर दूसरा विकल्प चुना जाता है
इसलिए on-prem product साल में एक बार update हो तो भी अजीब नहीं माना जाता
बड़े data footprint वाले enterprise software में अक्सर कोई बहुत छोटी चीज़ install तोड़ देती है और ops team rollback करती है
पुराने SharePoint upgrades तो लगभग पासा फेंकने जैसे लगते थे
यह भी Wiz की बड़ी उपलब्धि है,
और ऐसा turning point लगता है जो दिखाता है कि AI tools RE और intrusion path discovery को कितना आगे बढ़ा सकते हैं
security को आखिरकार security through obscurity पर निर्भर नहीं होना चाहिए — इसके पक्ष में एक और data point मिल गया
सब लोग GitHub का विकल्प ढूँढने की बात करते हैं, लेकिन फिर सवाल रहता है कि इस्तेमाल क्या करें
GitHub जैसे बड़े platform में भी अब RCE निकल रहा है, तो यह कहना आसान नहीं कि बाकी विकल्प ज़रूर बेहतर होंगे
https://news.ycombinator.com/item?id=46961345
https://news.ycombinator.com/item?id=47712656
और GitHub को केवल तब तक mirror की तरह इस्तेमाल करना जब तक free CI की ज़रूरत हो
secrets को किसी अलग secret-hosting provider को सौंपा जा सकता है
Forgejo इतना responsive है और GitHub इतना धीमा हो गया है, यह अब भी विश्वास करना मुश्किल लगता है
internal वाले private Forgejo instance में रखते हैं, और public वाले GitHub पर डालते हैं लेकिन Forgejo में mirror करते हैं
यह देखकर हैरानी हुई कि Forgejo लगभग single binary जैसा है और configure करना भी आसान है,
और हमने सभी internal services को Forgejo की ओर point कर दिया है, इसलिए GitHub छोड़ना पड़े तो भी friction कम रहेगा
all-in-one Docker image और कुछ GitLab runners छोटे से मध्यम आकार की teams के लिए काफ़ी हैं,
जब तक सचमुच ज़रूरत न हो, Kubernetes version तक जाकर चीज़ों को जटिल बनाने की कोई वजह नहीं
source code से AI का vulnerabilities ढूँढ लेना ही प्रभावशाली था,
लेकिन binary executables तक में यह कर लेना सचमुच चौंकाने वाला है
अच्छे और बुरे, दोनों अर्थों में इसमें बहुत बड़ी potential है
और एक बार फिर यह सबक सामने आता है कि data को command की तरह treat नहीं करना चाहिए
user input को पूरी तरह sanitize करना चाहिए
इसलिए source-to-source या text-to-source में इसका अच्छा होना कोई नई बात नहीं थी,
और asm versions को समझने में भी यह फिट बैठता है, तो यह पूरी तरह अप्रत्याशित नहीं हो सकता
फिर भी यह प्रभावशाली तो है ही
यह जानने की उत्सुकता है कि क्या यह वास्तव में exploit किया गया था
HTTP/git protocol logs से exploitation हुआ या नहीं, इसका कुछ अंदाज़ा तो लगाया जा सकता है,
लेकिन वास्तव में किस चीज़ तक पहुँच हुई और किसने किया, यह शायद दर्ज न हुआ हो
क्योंकि अगर exploit git server पर independently run हो सकता था, तो परिभाषा के अनुसार वह logging से बच निकल सकता था