- शोधकर्ता ने Nixpkgs की एक vulnerability खोजी और साझा किया कि कैसे इसके जरिए पूरे Nix इकोसिस्टम में malicious code inject किया जा सकता था
- GitHub Actions के
pull_request_target trigger के माध्यम से यह समझाया गया कि external contributor PRs में भी sensitive permissions और secrets उजागर होने का संरचनात्मक जोखिम है
- वास्तव में editorconfig-checker और code owners validation jobs में command injection और symbolic link के उपयोग से privilege escalation संभव होने का प्रमाण दिया गया
- खोज के तुरंत बाद Nixpkgs maintainers ने तेजी से vulnerability को patch किया, vulnerable workflows को disable किया और permission operations की दोबारा समीक्षा की
- यह जोर दिया गया कि संगठन की CI/CD infrastructure में untrusted data और sensitive operations को अलग रखना, least privilege देना, और policies को मजबूत करना बहुत महत्वपूर्ण है
पूरे Nix इकोसिस्टम को हैक करना
परिचय और पृष्ठभूमि
- पिछले साल NixCon में शोधकर्ता और उनकी सहयोगी Lexi ने Nixpkgs की vulnerability पेश की
- इस खोजी गई vulnerability ने supply chain attack के जरिए पूरे Nix इकोसिस्टम में malicious code डालने की संभावना खोल दी
- vulnerability detection से लेकर report और remediation तक की तेज प्रतिक्रिया सिर्फ एक दिन में पूरी हुई
- शोधकर्ता इस साल NixCon में शामिल नहीं हो सके, इसलिए इस लेख में पूरी प्रक्रिया को विस्तार से संकलित किया गया है
GitHub Actions: एक संवेदनशील लक्ष्य
- GitHub Actions कोड repositories में विभिन्न automation tasks (CI/CD) को सपोर्ट करने वाली एक system है
- workflow files तक access permission होने पर code injection आसान हो जाता है, और इसी कारण यह supply chain attack का प्रमुख target बनता है
- workflow files YAML में लिखी जाती हैं, और चूंकि यह execution के लिए डिज़ाइन किया गया format नहीं है, इसलिए इनमें अप्रत्याशित security vulnerabilities मौजूद हो सकती हैं
- एक साधारण उदाहरण के तौर पर, code push होने पर command चलाने वाला workflow मौजूद होता है
खतरनाक pull_request_target trigger
- GitHub Actions में कई triggers होते हैं, जिनमें pull_request_target सामान्य pull_request से काफी अलग है
- pull_request_target को forked PRs से भी default रूप से read/write permissions और secrets access मिल जाता है
- इस trigger का गलत इस्तेमाल होने पर untrusted external data sensitive permissions के साथ जुड़ जाता है
- GitHub के official docs में भी इस जोखिम के बारे में स्पष्ट चेतावनी दी गई है
- शोधकर्ता ने Nixpkgs repository में pull_request_target का उपयोग करने वाले 14 workflows की जांच की
editorconfig-checker vulnerability
- सबसे पहले मिली vulnerable workflow का उद्देश्य editorconfig rules check करना था
- बदली गई files की list निकालने के बाद उसे xargs के जरिए editorconfig-checker को दिया जाता था
- अगर xargs command की security warning को नजरअंदाज किया जाए, तो malicious तरीके से बनाए गए filename (जैसे
--help) को insert करने वाली vulnerability पैदा होती है
- इससे editorconfig-checker को मनमाने ढंग से manipulate किया जा सकता है, या आगे अतिरिक्त command execution की संभावना खुल सकती है (विस्तृत विश्लेषण के लिए और समीक्षा आवश्यक है)
codeowners-validator vulnerability: local file inclusion
- दूसरी और अधिक गंभीर vulnerability CODEOWNERS file validation workflow में मिली
- इस process में PR code को checkout करने के बाद codeowners-validator से file की जांच की जाती थी
- PR submitter OWNERS file को symbolic link से बदल सकता था, जिससे runner के अंदर किसी भी file को reference किया जा सकता था (जैसे action credentials)
- नतीजतन validation के दौरान उस file का content logs में प्रिंट हो जाता था, जिससे read/write permissions वाला GitHub token उजागर हो जाता था
- यह token मिल जाने पर Nixpkgs repository में सीधे push करना संभव हो जाता था
कार्रवाई और सबक
- vulnerability report के बाद Nixpkgs maintainer infinisil ने तुरंत प्रतिक्रिया दी
- vulnerable workflows को अस्थायी रूप से disable किया गया
- untrusted data और permissions के जुड़े हिस्सों को fix और अलग किया गया
- security fix के बाद workflow names बदलकर branch targeting issue को कम किया गया
- मुख्य सबक
- untrusted data को secrets और sensitive tasks के साथ कभी न जोड़ें, या अधिकतम सावधानी बरतें
- least privilege के सिद्धांत का पालन करें
- GitHub Actions permissions से जुड़ी official guide को समझना आवश्यक है
- ऐसी vulnerability होने पर संगठन का administrator policy के जरिए Actions को एक साथ disable कर सकता है (इसकी setup method भी दी गई है)
निष्कर्ष
- शोधकर्ता ने एक ही दिन में पूरे Nix इकोसिस्टम को खतरे में डाल सकने वाली vulnerability खोजी, रिपोर्ट की और fix में भाग लिया
- इससे GitHub Actions, खासकर pull_request_target के इस्तेमाल में विशेष सावधानी की जरूरत सामने आती है
- शोध में मदद करने वाले KITCTF के Intrigus और तेजी से प्रतिक्रिया देने वाले infinisil को धन्यवाद दिया गया
- रुचि रखने वाले पाठकों को presentation video और अतिरिक्त materials देखने की सलाह दी गई
- कुल मिलाकर, GitHub Actions security management की महत्ता और व्यावहारिक सीख पर जोर दिया गया
1 टिप्पणियां
Hacker News की राय
मुझे लगता है कि
pull_request_targetमूल रूप से security के लिहाज़ से कमजोर है, और GitHub को यह feature पूरी तरह हटा देना चाहिए। आम तौर पर कहा जाता है किpull_request_targetको सुरक्षित तरीके से इस्तेमाल करना हो तो branch द्वारा नियंत्रित code को job के दौरान चलाना नहीं चाहिए, लेकिन व्यवहार में argument injection या local file inclusion जैसी वजहों से attack surface इससे कहीं बड़ा हो जाता है। अभी इसके वैध use case ज़्यादातर third-party PR पर auto-labeling या auto-commenting तक सीमित हैं। ऐसे कामों के लिए repository पर by default write permission देने की ज़रूरत नहीं होनी चाहिए। GitHub को ऐसे कामों के लिए केवल उसी task तक सीमित token जारी करना चाहिए। इसलिए मैं zizmor मेंpull_request_targetजैसे खतरनाक triggers के इस्तेमाल पर हमेशा flag लगाता हूँ, देखें zizmor dangerous triggerspull_requestworkflow trigger नहीं होता। उस स्थिति मेंpull_request_targetpractically एकमात्र विकल्प रह जाता है। बेहतर होता कि GitHub non-clean-merge PR पर भी workflow चलाने की कोई setting देता, जो by default disabled रहती और सिर्फ linter जैसी चीज़ों के लिए उपयोग होती। तब तक इस limitation की वजह से सिर्फpull_request_targetपर निर्भर रहना पड़ना दुर्भाग्यपूर्ण है। वैसे, ऐसे external tool का उपयोग करते समय अगर GitHub पर manual merge कर दिया जाए तो पूरा flow टूट जाता है, इसलिए manual merge बिल्कुल नहीं करना चाहिएpull_request_targetदो कारणों से इस्तेमाल करते हैं। पहला, workflow हमेशा main के आधार पर चलता है, इसलिए unvalidated test code को रोका जा सकता है। दूसरा, workflow के अंदर JWT के sub claim मेंjob_workflow_refनिर्णायक रूप से मिलता है, जिससे OIDC-आधारित systems में fine-grained access control संभव होता हैpull_request_targetPR के base context में चलता है, इसलिए malicious code repository या secrets चुरा नहीं सकता। लेकिन वास्तव में secrets leak करना कितना आसान है, यह जानने के बाद यह बात कुछ हास्यास्पद लगती हैअगर Nix team ने मेरे प्रस्तावित RFC के अनुसार signed commits/reviews से अलग independently signed reproducible builds लागू किए होते, तो इस तरह के last-mile supply-chain attack संभव नहीं होते। आखिरकार NixPkgs चाहता है कि कोई भी आसानी से edit कर सके, और उसे डर है कि security पर ज़ोर देने की कोशिश से volunteers दूर हो जाएंगे, क्योंकि उसका फ़ोकस hobbyist distro पर है। यह ठीक है, लेकिन तब लोगों को यह बात साफ़-साफ़ बतानी चाहिए, और अगर सचमुच कीमती चीज़ों की सुरक्षा करनी है तो Nix को security-critical environments में इस्तेमाल या recommend करना बंद कर देना चाहिए। किसी चीज़ की रक्षा करने वाला OS हर बदलाव पर कठोर two-party hardware signing की मांग करे, और किसी एक मशीन या एक व्यक्ति पर trust नहीं छोड़े। इसी वजह से मैंने Stagex बनाया Stagex लिंक Codeberg लिंक
मैंने परंपरागत रूप से computer systems design किए हैं, इसलिए यह देखना बहुत चौंकाने वाला है कि आज के workflows अब भी bearer token—यहाँ तक कि short-lived token—उन programs को दे देते हैं जिन पर उन्हें trust करना पड़ता है। अगर GitHub Actions framework केवल privileged Unix socket या
ssh-agentaccess देता, तो ऐसे vulnerabilities का दुरुपयोग करना कहीं मुश्किल होताpull/merge requests के लिए CI/CD actions सचमुच एक दुःस्वप्न हैं। जब developers test या verification steps लिखते हैं, तो वे आमतौर पर यह मानकर लिखते हैं कि “मेरा code मेरे GitHub/GitLab account context में चलेगा।” यह उनके अपने या teammates के commits के लिए ठीक है, लेकिन PR में CI/CD pipeline untrusted code चलाती है। इस अंतर को हर समय ठीक-ठीक समझते रहना कठिन है। साधारण tests या linter चलाने तक तो ठीक है, लेकिन जैसे ही infrastructure integration की ज़रूरत पड़ती है और ज़्यादा permissions चाहिए होती हैं, चीज़ें जल्दी खतरनाक हो जाती हैं
pull_requestऔरpull_request_target। इनमें से एक (pull_request) आम तौर पर लगभग सुरक्षित है, जब तक उसे जानबूझकर गलत न इस्तेमाल किया जाए; जबकि दूसरा (pull_request_target) लगभग कभी सुरक्षित ढंग से उपयोग नहीं किया जा सकता। इससे भी बड़ी समस्या यह है that GitHub ने PR पर label लगाना, auto-comment करना जैसे सामान्य काम भी केवल इसी खतरनाक trigger (pull_request_target) में संभव बनाए हैं, इसलिए लोग मजबूरी में अस्थिर विकल्प चुनते हैं। GitHub Actions का feature set गलती करवाने वाली संरचना जैसा हैसमय बीतने के साथ supply-chain attacks को लेकर मेरी चिंता बढ़ती जा रही है। यह सिर्फ “क्या इससे मेरी नौकरी जाएगी?” या “NixOS, CI/CD, Node वगैरह में कोई नया attack vector निकल आया” जैसी चिंता नहीं रह गई है; यह अब अधिक दार्शनिक चिंता बन गई है। जितना ज़्यादा हम depend करते हैं, उतनी ही ज़्यादा समस्याएँ सँभालनी पड़ती हैं। आराम से इस्तेमाल करने के लिए बनाई गई चीज़ें भी पहले से बहुत उलझ चुकी हैं—VSCode, Emacs, Nix, Vim, Firefox, JS, Node, और इनके सारे plugins व dependencies आपस में गुँथे हुए हैं। इसलिए शर्मिंदगी के साथ मैं धीरे-धीरे उस अजीब निष्कर्ष की ओर जा रहा हूँ कि control या security का थोड़ा-बहुत एहसास पाने के लिए शायद कागज़ और सिर्फ़ बेहद minimal, बहुत simple तकनीक ही इस्तेमाल करनी चाहिए। मुझे पता है यह अव्यावहारिक है, लेकिन इस complexity से अब सचमुच ऊब होने लगी है। अब तो complexity threshold भी महसूस होने लगा है
xargsके man page में चेतावनी दी गई है कि “xargs को सुरक्षित रूप से उपयोग करना संभव नहीं है।” लेकिन यह security issue उस संदर्भ से अलग है जो यहाँ लागू हुआ। इस मामले में अंत में सिर्फ--जोड़ देना पर्याप्त है“xargs को सुरक्षित रूप से उपयोग नहीं किया जा सकता” वाली बात का अक्सर गलत अर्थ लगाया जाता है। उदाहरण के लिए,
cat "$HOME/changed_files" | xargs -r editorconfig-checker --की तरह चलाने पर यहाँ बताई गई खास समस्या से बचा जा सकता है<div>{escapeHtml(value)}</div>लगाकर XSS रोकना। अगर हर जगह manually safe usage लागू करना पड़े, तो तरीका ही मूल रूप से गलत है--जैसे argument separator को support नहीं करता, औरxargsके ज़्यादातर उपयोग argument injection के प्रति संवेदनशील होते हैं। दूसरे शब्दों में, हर command execution मूल रूप से risky है। यहxargsकी गलती नहीं, बल्कि वह वास्तविकता है जिसमें tools अलग-अलग privilege contexts में बार-बार उपयोग किए जाते हैंउस लेख में इससे भी व्यापक असर वाला एक गंभीर loophole है: PR code में OWNERS file को symlink में बदला जा सकता है ताकि GitHub Actions credential file जैसे किसी भी arbitrary file को expose किया जा सके। चूँकि git softlink commit को support करता है, लगभग किसी भी workflow में यह जोखिम पैदा हो सकता है
pull_request_targetके दौरान credentials target repo, यानी merge destination repo के context के होते हैं।pull_requestमें चलाने पर credentials attacker-controlled source repo के होते हैंएकमात्र “अच्छी” खबर शायद यह है कि OpenBSD और NetBSD अभी भी package management के लिए CVS इस्तेमाल करते हैं, इसलिए यह vulnerability उन्हें प्रभावित नहीं करती। FreeBSD के बारे में निश्चित नहीं हूँ। एक तरह से security through obscurity जैसा मामला है। हालांकि लगता है वे projects भी git migration पर विचार कर रहे हैं, और OpenBSD शायद got(1)-आधारित रास्ते पर जाएगा