- ओपन सोर्स पैकेज @ctrl/tinycolor को शामिल करने वाले कई npm पैकेज एक malicious version से संक्रमित हो गए; इसका कारण सहयोगी repository की GitHub Actions workflow के ज़रिए npm token की चोरी था
- हमलावर ने broad permissions वाले npm token का उपयोग करके लगभग 20 पैकेजों में malicious code deploy किया, जिनमें @ctrl/tinycolor का साप्ताहिक डाउनलोड 20 लाख तक होने से उसका प्रभाव बड़ा था
- संक्रमित versions ने postinstall चरण में malicious payload चलाया, और GitHub व npm security teams ने तेज़ी से प्रतिक्रिया देकर deletion और cleanup किया
- लेखक ने दोबारा ऐसी घटना रोकने के लिए Trusted Publishing(OIDC) में migration, token permissions को न्यूनतम करने, 2FA अनिवार्य करने, और pnpm features के उपयोग सहित मज़बूत security plan तैयार किया
- यह घटना software supply chain security की कमजोरियों को दिखाती है और npm ecosystem भर में security features के सुधार व security practices में बदलाव की ज़रूरत को उजागर करती है
TL;DR
- एक malicious GitHub Actions workflow को shared repository में push किया गया, जिसने npm token चुरा लिया
- उसी token से हमलावर ने 20 पैकेजों के malicious versions publish किए, जिनमें @ctrl/tinycolor की download volume अधिक होने से उसका असर बड़ा रहा
- व्यक्तिगत account या repositories सीधे compromise नहीं हुए, और न phishing हुई, न local malware install किया गया
- GitHub/npm security teams की तेज़ कार्रवाई से malicious versions हटा दिए गए, और बाद में cache साफ़ करने के लिए clean versions फिर से publish किए गए
घटना का पता कैसे चला (How I Found Out)
- 15 सितंबर की दोपहर, community member Wes Todd ने Bluesky DM के ज़रिए समस्या की जानकारी दी
- तब तक GitHub/npm security teams प्रभावित पैकेजों की सूची तैयार कर deletion शुरू कर चुकी थीं
- शुरुआती संकेत के रूप में 'Shai-Hulud' नाम की malicious branch साझा की गई, जो Dune ब्रह्मांड के sandworm के नाम से ली गई थी
वास्तव में क्या हुआ (What Actually Happened)
- बहुत पहले साथ काम किए गए angulartics2 repository में अब भी admin permissions वाला एक collaborator मौजूद था
- उस repository में संग्रहीत npm token को malicious GitHub Actions workflow ने चुरा लिया
- हमलावर ने इसी token से @ctrl/tinycolor सहित लगभग 20 पैकेज publish किए
- GitHub/npm security teams ने तेज़ी से malicious versions हटा दिए, और लेखक ने भरोसेमंद नए versions दोबारा publish किए
प्रभाव (Impact)
- malicious version install होने पर postinstall script चलती थी, जिससे security threat पैदा होता था
- प्रभावित users को StepSecurity के तुरंत response guidance देखने की सलाह दी गई
पब्लिशिंग सेटअप और अंतरिम योजना (Publishing Setup & Interim Plan)
- पहले semantic-release + GitHub Actions के संयोजन से automated publishing की जाती थी
- npm के provenance feature का उपयोग किया गया था, लेकिन यह valid token वाले हमलावर को नहीं रोक सका
- आगे चलकर Trusted Publishing(OIDC) अपनाकर static tokens हटाने की योजना है
- फिलहाल सभी tokens रद्द कर दिए गए हैं और 2FA अनिवार्य, granular permissions वाले token ही अनुमत, तथा pnpm के minimumReleaseAge feature की समीक्षा जैसे अतिरिक्त security measures लागू किए जा रहे हैं
आदर्श सुधार (Publishing Wishlist)
- npm account स्तर पर OIDC-आधारित Trusted Publishing को अनिवार्य करने का विकल्प उपलब्ध होना चाहिए
- provenance न होने पर publishing block करने की सुविधा, और semantic-release व OIDC के पूर्ण integration का समर्थन होना चाहिए
- GitHub UI में 2FA-आधारित manual approval publishing feature उपलब्ध कराया जाना चाहिए
- Pro subscription के बिना भी GitHub Environments स्तर के protection features इस्तेमाल किए जा सकें
- npm package page पर postinstall script की मौजूदगी का संकेत और हटाए गए versions के कारण सार्वजनिक किए जाने चाहिए
1 टिप्पणियां
Hacker News राय
उस रिपॉज़िटरी में अब भी GitHub Actions secrets बचे हुए थे, यानी ऐसा npm token जिसके पास व्यापक publish permissions थीं
Trusted Publishing का एक बड़ा फायदा यह है कि अब लंबे समय तक वैध रहने वाले publish token की ज़रूरत नहीं रहती
अब सिर्फ CI VM में थोड़े समय के लिए बनाए गए token इस्तेमाल होते हैं और token केवल 15 मिनट तक वैध रहता है
यह पहले से PyPI, npm, Cargo, Homebrew जैसे कई ecosystems में लागू है
इससे publish process वास्तव में थोड़ा आसान भी हो जाता है, इसलिए मैं सभी को इसे इस्तेमाल करने की सलाह दूँगा
अगर documentation अब भी अस्पष्ट लगे तो कभी भी मदद माँगी जा सकती है
ecosystem maintainers भी चाहते हैं कि यह feature व्यापक रूप से अपनाया जाए
Trusted Publishing आधिकारिक दस्तावेज़ देखें
मुझे तो इस बार पहली बार पता चला कि npm में अब Trusted Publishing संभव है
संबंधित समाचार
मैं इसे इसी वीकेंड सेटअप करने वाला हूँ
अच्छा होगा अगर अब कोई flag हो जिससे repository में दिखे कि यह project ऐसे features इस्तेमाल करता है
तब उन dependency packages को आसानी से block किया जा सकेगा जो इसका उपयोग नहीं करते
ऐसा लगता है कि automated deployment process में MFA (multi-factor authentication) शामिल करने वाले मुद्दे पर पर्याप्त ध्यान नहीं दिया गया
CI workflow से publish करते हुए MFA prompt के ज़रिए publication confirm करना अपने-आप में समस्या नहीं है, लेकिन जब मैंने पिछली बार देखा था तब code उपलब्ध कराने के लिए HTTPS tunnel खोलनी पड़ती थी, जिससे चीज़ें जटिल हो जाती थीं
अच्छा होगा अगर npm या GitHub सीधे ऐसा तरीका दें जिससे CI के दौरान MFA code आसानी से दिया और confirm किया जा सके
package publishing के दो चरण होते हैं: package को npmjs पर upload करना और फिर उसे वास्तव में users के लिए public करना
फिलहाल ये दोनों चरण एक ही काम में बँधे हुए हैं
मेरे हिसाब से इन्हें अलग होना चाहिए, ताकि CI system अपने-आप सिर्फ build और upload करे
और uploaded package को सच में deploy करने के लिए किसी इंसान को npmjs website पर खुद login करके manual publish और MFA पूरा करना पड़े
सच कहूँ तो कभी-कभी लगता है कि package publish करने की धारणा ही ज़रूरी नहीं है
अगर VCS ही “वास्तविक source” है, तो बिना अलग publishing process के सीधे वहीं से इस्तेमाल क्यों न किया जाए
Go भाषा वास्तव में ऐसा करती है
वह URL आधारित तरीके से package को सीधे import करती है और versioning tags से संभालती है
इस तरह सिर्फ VCS पर भरोसा करना पड़ता है, इसलिए अतिरिक्त attack surface कम हो जाता है
अलग archive files का diff देखने की ज़रूरत नहीं, सिर्फ commits को verify करना होता है
समस्या यह है कि repository स्थानांतरित होने पर import path बदल जाता है, लेकिन इसे एक तरह का फायदा भी माना जा सकता है
इसके अलावा अलग publish step होने का फायदा क्या है, यह मुझे साफ़ नहीं है
यह पुराने FTP से tar archives upload करने वाले दौर की विरासत जैसा लगता है
मैंने पहले angulartics2 नाम की shared repository पर काम किया था
वहाँ अब भी GitHub Actions secret में ऐसा npm token पड़ा था जिसके पास व्यापक publish permissions थीं
किसी contributor के पास कई projects की permissions भी थीं, और शायद इसी वजह से कई packages एक साथ प्रभावित हुए
Shai-Hulud नाम की नई branch को malicious github action workflow के साथ force push किया गया
क्योंकि वह admin permission वाला contributor था, workflow बिना review के तुरंत चल गया और npm token लीक हो गया
लीक हुए token से 20 packages के malicious versions publish कर दिए गए
ज़्यादातर packages बहुत अधिक उपयोग में नहीं थे, लेकिन @ctrl/tinycolor एक लोकप्रिय package है जिसके लगभग 20 लाख downloads प्रति सप्ताह हैं
जो बात मुझे अब भी समझ नहीं आती, वह यह है कि angulartics2 repository का npm token tinycolor तक publish कैसे कर सकता था
मेरे पास भी किसी और के npm repository में admin permission है और हाल की releases लगभग मैंने ही की हैं
admin बनने के बाद मुझे लगा कि इस बहाने पुराने पड़े issues भी ठीक कर दूँ, इसलिए commits में मेरा नाम भी ज़्यादा दिखने लगा
मैं लगभग GitHub action से package publish करने के पक्ष में हो गया था, लेकिन 2FA के साथ manually deploy करते समय हमेशा यह डर रहता था कि कहीं master के बजाय गलत state publish न हो जाए
इसी वजह से मैंने इस मुद्दे पर दूसरे admins से बात करना भी टाल रखा था, और अब जो हुआ उसे देखकर लगता है कि टालना शायद ठीक था
सही जवाब क्या है, पता नहीं, लेकिन credentials किसी third party को सौंप देना निश्चित रूप से अच्छा समाधान नहीं लगता
अगर मेरी बात स्पष्ट नहीं थी तो माफ़ी
यह token मेरे सभी npm packages पर global publish permission वाला token था
मैं पिछले 10 सालों से manual releases की वकालत करता आया हूँ
मुझे हमेशा काफी विरोध मिला, लेकिन अब यह विचार इतना अजीब नहीं लगता
मुझे पता है CI/CD आकर्षक है, लेकिन यह घटना और हाल के CF issues देखकर उल्टा यह सबूत बढ़ रहा है कि automation गंभीर समस्याएँ पैदा करने में मदद कर सकता है
जब मैं BigBank में काम करता था, तब production deploy के लिए कम से कम पाँच लोग साथ मौजूद रहते थे और बहुत सारी प्रक्रियाएँ होती थीं, लेकिन कम-से-कम यह साफ़ होता था कि क्या deploy किया जा रहा है
मुझे नहीं लगता कि GitHub Actions या automated release scripts की तुलना में पुरानी तरह से खुद build करना, sign करना, tarball upload करना और verify करना कम सुरक्षित है; बल्कि वह अधिक सुरक्षित लगता है
distribution systems (जैसे Debian का distribution packaging system) में अतिरिक्त verification steps भी होते हैं, और यही एक कारण है कि xz घटना में पूरा इंटरनेट compromise नहीं हुआ
कम-से-कम release publish होने से पहले किसी इंसान द्वारा binary पर sign करना अनिवार्य होना चाहिए
चूँकि attacker खुद को maintainer के रूप में जोड़कर अपनी key से sign भी कर सकता है, इसलिए distribution packaging systems की तरह trusted key management भी साथ होना चाहिए
अगर मेरा threat model यह है कि “बस एक GitHub account या API key लीक होते ही सारे users compromise हो जाएँगे”, तो मुझे खुद से पूछना चाहिए कि क्या यह सच में उचित है
publishing में 2FA होना अच्छी बात है, लेकिन अगर कई authors को cryptographic signature के साथ सहमति देनी पड़े तो यह कहीं अधिक सुरक्षित होगा
ऐसा होना चाहिए कि सिर्फ एक व्यक्ति के compromise होने से हमला सफल न हो
बहुत से packages में author सिर्फ एक ही होता है
कई authors की signatures माँगना अच्छा है, लेकिन commits, tags, artifacts आदि पर किसी-न-किसी रूप में signature verification हो तो ज़्यादातर हमले रोके जा सकते हैं
distribution packaging में signature verification का अच्छा समर्थन है, लेकिन language package managers में ऐसे verification frameworks कमज़ोर हैं
उदाहरण के लिए runc की आधिकारिक release process में सब कुछ maintainer keys से signed होता है, और keys Yubikey जैसी devices में रखी जाती हैं
distribution systems भी अलग keyring संभालते हैं और official source व binaries को verify करते हैं
अगर ऐसी प्रक्रिया होती, तो मुझे लगता है यह हमला कई चरणों में रोका जा सकता था
CI में build अपने-आप हो सकता है, लेकिन अंतिम चरण में maintainer द्वारा direct signing ज़रूरी है
अगर language package managers में ऐसा workflow नहीं है, तो Trusted Publishing कम-से-कम तुलनात्मक रूप से कम बुरा विकल्प है
लेकिन अगर GitHub account compromise हो जाए (जैसे cookie theft), तो publish फिर भी किया जा सकता है
GitHub Trusted Publishing के लिए timeout जैसी security settings देता है, लेकिन attacker उन्हें बंद भी कर सकता है
मेरे account के compromise हो जाने पर भी distribution system वह बदलाव स्वीकार नहीं करेगा जिस पर मेरी sign की हुई key न हो, इसलिए वह अपेक्षाकृत अधिक सुरक्षित है
संदर्भ: मैं SUSE से जुड़ा हूँ, लेकिन चाहता हूँ कि openSUSE, Arch, Gentoo जैसी distributions में artifact verification support और बढ़े
संबंधित links:
runc.keyring
keyring_validate.sh
release_sign.sh
openSUSE का runc.keyring
मुझे tokens से नफ़रत है
token असल में static password जैसा ही है
मुझे लगता है कि इससे बेहतर authentication method चाहिए
उदाहरण के तौर पर GitHub को AWS के token provider की तरह इस्तेमाल करना मुझे अपेक्षाकृत बेहतर लगता है
Github-AWS OIDC integration तरीका
हालाँकि यह एक अपवाद जैसा मामला है
machine-to-machine OIDC flow सही तरह implement किया जाए तो सुरक्षित हो सकता है, लेकिन इसकी configuration बहुत जटिल है
और अंत में OIDC भी “ज़्यादा जटिल token” जैसा ही लगता है
अगर environment automated है और इंसान सीधा verify नहीं कर रहा, तो कहीं-न-कहीं कुछ ऐसा रहेगा जो leak हो सकता है—चाहे token हो या token generator
इस worm वाली घटना में भी OIDC मूल समाधान नहीं था
अगर GitHub workflow compromise हो गया हो, तो OIDC हो या न हो, environment में अस्थायी identity inject हो ही जाएगी
आख़िरकार महत्वपूर्ण बात यह है कि कोई अनधिकृत उपयोगकर्ता secrets वाले workflow चला न सके
अगर बहुत सूक्ष्म permissions चाहिएँ, तो OIDC से बेहतर शायद token scope को कम करना हो सकता है
token का मूल उद्देश्य यही था कि उसकी lifetime और authZ scope सीमित हो
लेकिन ज़्यादातर मामलों में ऐसा व्यवहार में नहीं होता और वह बस password की तरह static इस्तेमाल होता है
oauth और biscuits जैसे alternatives मौजूद हैं जिनमें granular permission restriction संभव है, लेकिन व्यवहार में उनका बहुत कम इस्तेमाल होता है
Trusted Publishing अब npm सहित कई package registries में supported है
संबंधित समाचार
जैसा दूसरे लोगों ने भी कहा, token केवल short lifetime के साथ या manual authentication (MFA, passphrase आदि) के बाद ही जारी किए जाने चाहिए
mTLS (TLS client certificates) इस्तेमाल करना शायद सही दिशा के सबसे क़रीब है
क्या किसी को vulnerable npm packages जाँचने के लिए कोई public tool/script पता है?
stepsecurity page पर ऐसा tool दिखाई नहीं देता
यह सब कुछ नहीं रोकता, लेकिन provenance-action अपनाना भी अच्छा विचार हो सकता है
provenance-action
ज्ञात issues के लिए
npm auditबुनियादी tool हैमेरा मतलब बस इतना था कि local publishing में गलत branch, build छूट जाना जैसी मानवीय गलतियों का डर रहता है
यह भी सोचने वाली बात है कि अगर CI job force push करके git history के बहुत गहरे हिस्से में बदलाव कर दे तो क्या होगा
मौजूदा व्यवस्था अब ठीक से काम नहीं कर रही
बिल्कुल, OIDC tokens, zero-trust solutions जैसी तकनीकी खूबियों की प्रशंसा की जा सकती है
लेकिन लाखों downloads वाले npm libraries के काफी maintainers असल में तब तक security पर ध्यान नहीं देंगे जब तक वे hack न हो जाएँ या npm खुद distribution रोक न दे
और फिर “सारी dependencies हटा दो और सिर्फ standard library रखो” जैसे अव्यावहारिक तर्क सामने आते हैं
dependencies कम करना अच्छी बात है, लेकिन जो समस्या पहले से मौजूद है उसका यह कोई समाधान नहीं
व्यवहारिक रूप से देखें तो या तो दस हज़ारों-लाखों लोग npm छोड़कर अपना code दोबारा लिखें, या npm ही high-download packages के लिए 2FA, OIDC जैसी नीतियाँ अनिवार्य करे और पालन न होने पर publish रोक दे
दोनों में कौन-सा विकल्प वास्तविक रूप से अधिक लागू करने योग्य है, यह साफ़ है
वरना npm की प्रतिष्ठा गिरती जाएगी और अंत में XKCD 927 जैसी स्थिति बन जाएगी