- 8 सितंबर को लोकप्रिय npm पैकेजों में malware injection का पता चला
- कुल 18 पैकेज प्रभावित हुए, जिनकी वैश्विक स्तर पर हर हफ्ते 2 अरब से अधिक downloads हैं
- हमलावरों ने ऐसा कोड शामिल किया जो वेबसाइट विज़िटर्स के ब्राउज़र में cryptocurrency और Web3 गतिविधियों को चुपचाप intercept करता है, और वॉलेट के approvals तथा fund flow को हमलावर के अकाउंट की ओर redirect कर देता है
- यह पुष्टि हुई कि मुख्य पैकेज फ़ाइल (
index.js) में obfuscated JavaScript code जोड़ा गया था
- यह जुड़ी हुई घटना टार्गेट पैकेज अपडेट्स के साथ ही शुरू हुई, और फिलहाल community इसका जवाब दे रही है
घटना का सार
- 8 सितंबर 13:16 UTC तक, Aikido की security monitoring feed में यह देखा गया कि npm पर malware शामिल करने वाले कई पैकेज अपलोड किए जा रहे थे
- ये पैकेज npm पर बेहद लोकप्रिय हैं और एक हफ्ते में 2 अरब से अधिक downloads दर्ज करते हैं
हमले का तरीका और विवरण
- malicious update के बाद यह पाया गया कि इन पैकेजों का उपयोग करने वाली वेबसाइटों के विज़िटर्स के ब्राउज़र में JavaScript malware गुप्त रूप से चलने लगता है
- इस कोड का मकसद cryptocurrency और Web3 गतिविधियों की निगरानी, वॉलेट interaction में हेरफेर, और payment destination address को बिना अनुमति बदलना है
- यूज़र को स्क्रीन पर कोई खास बदलाव दिखे बिना, फंड और approval permissions हमलावर द्वारा तय किए गए cryptocurrency address पर भेजे जा सकते हैं
malicious code का विस्तृत विश्लेषण
- उदाहरण के तौर पर,
is-arrayish आदि में index.js फ़ाइल से छेड़छाड़ कर obfuscated और जटिल JavaScript डाली गई थी
- कोड में
window.ethereum interface का इस्तेमाल करके वॉलेट अकाउंट जानकारी की जांच की जाती है और attack code चलाने की शर्तों की पुष्टि की जाती है
- अंदरूनी तौर पर कई cryptocurrency addresses (Bitcoin, Ethereum आदि) और function logic शामिल हैं, तथा वॉलेट address और transaction details को हमलावर के address से बदलने की क्षमता लागू की गई है
- इसके कारण वास्तविक यूज़र्स की cryptocurrency assets बिना जानकारी के लीक होने और अनधिकृत transfer का जोखिम पैदा होता है
मौजूदा स्थिति और community की प्रतिक्रिया
- संबंधित malicious package versions को प्रमुख npm repositories से तेजी से हटाया जा रहा है
- IT/open source community में संबंधित पैकेजों का उपयोग रोकने और upgrade guidance, अतिरिक्त infection detection और response activities सक्रिय रूप से चल रही हैं
- इस हैकिंग घटना ने package supply chain security, code obfuscation detection, और Web3 browser extension protection को लेकर जागरूकता को काफी बढ़ा दिया है
2 टिप्पणियां
> 8 सितंबर 2023,
मतिभ्रम की वजह से तारीख गलत आ गई थी। यह 2023 की बात नहीं है, बल्कि अभी की है।
npm के बारे में हैकिंग की खबरें काफ़ी अक्सर सुनने को मिलती हैं। लगता है कोई समस्या है।
Hacker News राय
हाँ, मैं हैक हो गया था। सच में शर्मनाक है और सब से माफ़ी चाहता हूँ। कृपया विवरण यहाँ और यहाँ देखें। प्रभावित पैकेजों की सूची भी डाल दी है। यह हमला targeted लगता है। कमेंट एडिट करने की समय-सीमा खत्म होने तक मैं लगातार अपडेट देता रहूँगा। Chalk पैकेज को मैंने रिकवर कर लिया है, लेकिन बाकी अभी भी compromise हुए हैं (8 दिन 17:50 CEST). NPM की तरफ़ से अभी तक कोई खबर नहीं है। मेरा NPM अकाउंट अभी एक्सेस नहीं हो रहा, और password recovery भी काम नहीं कर रही। इस समय मैं बस इंतज़ार ही कर सकता हूँ। support टीम का ईमेल npmjs dot help से आया था, और काफ़ी असली जैसा लग रहा था। यह कोई बहाना नहीं है, लेकिन वह थका हुआ सुबह का समय था, और एक काम जल्दी निपटाने की कोशिश में मैंने आदतन official homepage पर खुद जाने के बजाय लिंक पर क्लिक कर दिया — शायद इसलिए भी क्योंकि मैं मोबाइल पर था। इस हमले का असर सिर्फ़ NPM पर पड़ा है, और मैं
/debug-jsलिंक पर आगे भी अपडेट देता रहूँगा। एक बार फिर सच में माफ़ी चाहता हूँइतने stressful हालात में भी आपने तेज़ और transparent तरीके से प्रतिक्रिया दी, यह सच में मिसाल है। लगता है कि अब मैं phishing में नहीं फँसूँगा, लेकिन कुछ tips जोड़ना चाहूँगा: 1) ईमेल लिंक से कभी लॉगिन मत कीजिए। phishing और वैध ईमेल में फ़र्क करना इतना मुश्किल है कि बचने का एकमात्र पक्का तरीका है कि कोशिश ही न करें। 2) अगर 2FA के लिए U2F/Webauthn security key इस्तेमाल करें, तो phishing से लगभग पूरी सुरक्षा मिलती है। TOTP ऐसा नहीं कर पाता, यह ध्यान रखें। आखिर इंसान थका हुआ या व्यस्त होने पर कभी भी गलती कर सकता है। इस बार बस आप निशाना बन गए। फिर से कहना चाहूँगा कि आपने स्थिति बहुत अच्छी तरह संभाली
sindresorhus के निर्देश के अनुसार, dependency tree में malware है या नहीं यह नीचे दिए गए कमांड से जाँच सकते हैं:
rg -u --max-columns=80 _0x112fa8(ripgrep चाहिए, इंस्टॉल के लिएbrew install rg). मूल कमेंट भी देखेंकॉलेज के समय मैं भी एक बार नशे में phishing का शिकार हुआ था (बहुत पुरानी बात है)। कोई भी शिकार हो सकता है। लेकिन NPM की प्रतिक्रिया इतनी धीमी है, यह हैरान करने वाला है। लगता है इससे हमलावर को ही ज़्यादा फ़ायदा होगा
Socket ने इस घटना को तुरंत detect कर लिया था। संबंधित ब्लॉग में भी इसका ज़िक्र है। यह घटना दुर्भाग्यपूर्ण है, लेकिन open source ecosystem ने बहुत तेज़ प्रतिक्रिया दी, यह अच्छी बात है। ऐसी घटनाएँ फिर याद दिलाती हैं कि package scanning क्यों ज़रूरी है
जल्दी चेतावनी देने के लिए धन्यवाद। मैंने porkbun को domain block करने का अनुरोध ईमेल भेज दिया है
इस malicious payload में एक चालाक हिस्सा है जिसे पर्याप्त ध्यान नहीं मिला। यह wallet address को बस random तरीके से replace नहीं करता, बल्कि सही address और अपनी सूची में मौजूद addresses के बीच Levenshtein distance निकालकर सबसे मिलता-जुलता attacker wallet चुनता है। यानी इसे इस तरह डिज़ाइन किया गया है कि लोग जो आम तौर पर address की सिर्फ़ शुरुआत और अंत देखकर verify करते हैं, उस आदत को bypass किया जा सके। payload को पूरी तरह deobfuscate करके इस विशेष व्यवहार सहित उसका विश्लेषण किया गया है, और विस्तार से लिखी गई पोस्ट भी है। सब लोग सुरक्षित रहें
उस लेख का एक हिस्सा मुझे उलझा रहा है। मेरी समझ थी कि package-lock.json में specific version को "exactly" pin किया जाता है। package.json में तो "x version या उससे ऊपर" जैसी definition हो सकती है, लेकिन lockfile में हर dependency का तय version और tarball URL सीधे दर्ज होता है। अगर lockfile मौजूद हो, तो CI environment में packages अपने आप update नहीं होने चाहिए। समझ नहीं आ रहा कि मैं npm/yarn/pnpm lockfile के व्यवहार को ग़लत समझ रहा हूँ या नहीं। कृपया npm official docs का यह उद्धरण भी देखें
मुझे लगता है कि अगर hash value को हर character के लिए अलग रंग (foreground/background) में, hash और index से तय color scheme के साथ दिखाया जाए, तो नज़र से मिलते-जुलते fake hash को अलग पहचानना कहीं आसान होगा
क्या इस बात का कोई संकेत है कि यह तकनीक किसी खास hacking group से जुड़ी हुई है?
यह attack code चालाक ज़रूर है, लेकिन सच कहें तो web पर ऐसे similar-address attacks से दशकों से निपटा जा रहा है, और यह बस उसका ज़्यादा dynamic version है। इसे बहुत असाधारण बताना मुझे ठीक नहीं लगता। ईमानदारी से कहूँ तो पूरी analysis post कहीं-कहीं AI द्वारा लिखी हुई जैसी लगती है, इसलिए यह बहुत सावधान विश्लेषण नहीं लगती
12 दिन पहले जब Nx के साथ भी यही हुआ था, तब मैंने ऐसी ही टिप्पणी लिखी थी। यह किसी एक व्यक्ति की विफलता नहीं, पूरे industry की विफलता है। supply chain attacks का प्रभाव बहुत बड़ा होता है, और मेरे हिसाब से इनमें से कई समस्याएँ पहले से हल की जा सकने वाली थीं। हम software developers हैं, इसलिए standard security measures — code signing, artifact signing, account anomaly detection, 2FA वगैरह — को अगर व्यापक रूप से लागू करें तो इन्हें रोका जा सकता है। आज भी सभी packaging platforms यह नहीं करते, और इसका कारण तकनीकी सीमा नहीं बल्कि यह है कि कोई उन्हें मजबूर नहीं करता। AI की प्रगति और real-world attacks की लगातार सफलता के कारण यह आगे और गंभीर होगा। अब समय आ गया है कि मज़बूत security standards को 'अनिवार्य' बनाया जाए
इन security measures के अपने trade-offs हैं। उदाहरण के लिए, heuristic या proof-based controls लगाने पर काफ़ी automation systems या सामान्य users बाहर रह सकते हैं। SMS-based 2FA कमज़ोर है, और ईमेल भी phishing के जोखिम से भरा है। TOTP तभी अर्थपूर्ण है जब open standard के रूप में इस्तेमाल हो, लेकिन तब भी यह phishing को पूरी तरह नहीं रोकता। सिर्फ़ hardware-based authentication ही वास्तव में असरदार है, लेकिन बड़े platforms पर उसे व्यावहारिक रूप से लागू करना कठिन है
यह बात इतनी simple नहीं है कि "security standards ठीक से पालन करो और सब रुक जाएगा"। चाहे कितने भी अच्छे security measures हों, अगर इंसान गलती करे तो पूरा system कमजोर हो जाता है। पूरी तरह सुरक्षित system जैसा कुछ नहीं होता। AI की प्रगति के साथ phishing mails असली से अलग न पहचान पाने लायक होती जा रही हैं, लेकिन दूसरी तरफ़ AI का इस्तेमाल करके ऐसे attacks को बेहतर detect भी किया जा सकता है। अंततः हमें AI से ही बचाव करना पड़ेगा
पहले ज़्यादातर hacking Windows को निशाना बनाती थी, लेकिन अब JavaScript और Python developers की संख्या बहुत ज़्यादा है। आगे ऐसे हमले और बढ़ेंगे
मुझे लगता है NPM की भी कुछ ज़िम्मेदारी है। अलग-अलग external security vendors और startups ऐसी malicious activity जल्दी पकड़ लेते हैं, तो फिर NPM, जिसके पास सभी packages और security events की real-time visibility है, बार-बार इतना बेबस क्यों दिखता है, समझना मुश्किल है। यह लगभग जानबूझकर अनदेखा करने जैसा लगता है
NPM अब GitHub, यानी Microsoft के स्वामित्व में है। शायद वे Copilot जैसी generative AI को हर app में डालने में ज़्यादा व्यस्त हैं
जिन packages को कई लोग maintain करते हैं, उनमें कम से कम ऐसा option होना चाहिए कि deploy तभी हो जब कोई दूसरा maintainer publish को approve करे
एक ही attacker ने लंबे समय से निष्क्रिय पड़े 22 से अधिक packages में obfuscated — और काफ़ी संदिग्ध दिखने वाला — payload एक साथ डालकर एक साथ publish किया। NPM से यह पकड़ने की उम्मीद करना लगभग असंभव है। मैं खुद दूसरे software platforms पर apps/extensions publish कर चुका हूँ, जहाँ कभी-कभी कई दिन या हफ़्तों तक approval का इंतज़ार करना पड़ता है। लेकिन यह देखकर हैरानी होती है कि NPM में, जबकि MS और GitHub हर तरह के security solutions बेचते हैं, service में वैसा निवेश नज़र ही नहीं आता
मुझे तो नहीं लगता कि NPM के पास कुछ बदलने की कोई खास वजह भी है। यह 10 साल से ज़्यादा समय से malware distribution का स्रोत रहा है, लेकिन कोई इसका इस्तेमाल बंद नहीं करता, इसलिए business पर भी कोई असर नहीं पड़ता
एक कारण package managers का बहुत ज़्यादा फैलाव भी है। मुझे शुरू से ही इतनी तुच्छ चीज़ों के लिए dependencies लेना पसंद नहीं था। random latest versions खींच लेने से environment टूट जाना भी बहुत बुरा लगता है। सिर्फ़ npm नहीं, आम तौर पर package managers ही परेशान करने वाले हैं
अब अगर कोई password manager के बिना, किसी ऐसे website पर सीधे password डालता है जिसका domain official domain से मेल नहीं खाता, तो मुझे लगता है उसे इंटरनेट पर कोई महत्वपूर्ण काम नहीं करना चाहिए
password manager/browser autofill ऐसे spoofed domains के बारे में चेतावनी दे देता, और इस NPM phishing जैसे मामले में npmjs.help और official domain के mismatch को भी रोक सकता था
यह बात सही है, लेकिन मैंने कई बार ऐसी situation देखी है जहाँ official app और website पूरी तरह अलग domains इस्तेमाल करते हैं। सबसे बुरा तब होता है जब mobile app और web का domain ही अलग हो। पता नहीं यह डिज़ाइन कौन करता है
हर बार ऐसी घटना होने पर मुझे समझ नहीं आता कि package registries सभी packages के लिए cryptographic signing अनिवार्य क्यों नहीं करतीं। हाँ, अगर CI/CD automation के जरिए signing हो और वही compromise हो जाए तो इसे भी bypass किया जा सकता है, लेकिन अधिकांश समस्याएँ फिर भी रुक सकती हैं। इसका मतलब यह होगा कि developers को artifacts download करना, sign करना, upload करना जैसी कुछ अतिरिक्त manual steps करनी पड़ेंगी
असली registry तो Debian की तरह यह पहले से करती है। npm काफ़ी amateurish है, इसलिए कई enterprise environments में इसके इस्तेमाल पर रोक होती है
मुझे सबसे अच्छा post-hoc verification वाला मॉडल लगता है। CI/CD से automated upload हो जाए, लेकिन web पर किसी इंसान को एक बार और क्लिक करके actual deployment approve करना पड़े। इससे release process में friction कम रहेगा, फिर भी एक human approval step रहेगा
लेकिन फिर भी मुश्किल सवाल बचता है: "किस signing key पर भरोसा किया जाए?" क्योंकि जिसकी 2FA compromise हो चुकी हो, वह भी नई key अपलोड करके sign कर सकता है। इसलिए शायद संदिग्ध account activity detect होने पर नई signing keys के registration में delay जैसी व्यवस्था चाहिए
मैंने यह निष्कर्ष निकाला है कि npm registry से बचना ज़्यादा फ़ायदेमंद है। इसके बजाय packages सीधे (git) repositories से लाने चाहिए। npm registry supply chain attacks का मुख्य रास्ता भी है, और इसमें source तथा published code के पूरी तरह अलग होने की समस्या भी है।
npm publishlocal की किसी भी code को सीधे अपलोड कर सकता है, इसलिए कोई दुर्भावनापूर्ण user आसानी से malicious code डाल सकता हैGitHub builds से npm पर publish करते समय authenticity verification का कोई mechanism है, लेकिन फिर भी लगता है कि दूसरे environments से publish करना संभव है, इसलिए मैं इसे पूरी तरह समझ नहीं पाया हूँ
C developer होने के नाते, यह थोड़ा अजीब लगता है कि dependency minimization, single-header libraries, और vendoring जैसी चीज़ों को कभी पुराने ज़माने का तरीका कहकर खारिज किया जाता था, और अब धीरे-धीरे सबको फिर समझ आ रहा है कि इनकी ज़रूरत थी
npm की हाल की provenance feature इस समस्या को address करती है। इसे configure करना भी काफ़ी आसान है, और यह ऐसे attacks को रोकने में मदद करेगी। बड़े packages इसे एक-एक करके अपनाते दिख रहे हैं, यह देखना अच्छा है
क्या लोग CI environments में भी यही तरीका इस्तेमाल करते हैं? यानी server पर
npm installसे लाने के बजायgit cloneसे dependencies लाते हैं?"git repository से सीधे package लाना" सिद्धांत में अच्छा लगता है, लेकिन व्यवहार में npm में bugs बहुत हैं, और git dependencies install करने से जुड़े issues भी पड़ते हैं। इस issue में जैसा मैंने लिखा है, build step की समस्याओं के कारण 2020 तक यह ठीक से काम नहीं करता था, और globally npm install करने पर अब भी दिक्कतें हैं। यहाँ तक कि अगर npm docs में prepack script का ज़िक्र है, तब भी व्यवहार में यह git-based dependencies पर काम नहीं करती। TypeScript compiler team को भी इस bug की वजह से अजीब workaround अपनाना पड़ा था, और fix वाला code तथा bug report भी मौजूद हैं। prepack fail होने पर exit code पास नहीं किया जाता, इसलिए
npm installटूटी हुई स्थिति में ही खत्म हो जाता है। यह सब देखकर लगता है कि npm को या तो कड़ी operational oversight की ज़रूरत है, या फिर इसे किसी नए package manager से बदल देना चाहिएnpm ecosystem के बाहर से देखने पर मुझे हैरानी होती है कि इतने सारे packages इतनी छोटी-छोटी बातों के लिए आखिर क्यों इस्तेमाल किए जाते हैं
वजह यह है कि standard library बहुत कमज़ोर है, और basic functionality के लिए भी external packages की ज़रूरत पड़ती है। अगर खुद बनाना हो तो छोटी-सी चीज़ के लिए भी बहुत implementation करनी पड़ती है
15 साल के development experience के आधार पर कहूँ तो, कई पेशेवर JavaScript developers वास्तव में coding में बहुत कमज़ोर होते हैं। यह बुद्धिमत्ता का नहीं, बल्कि training और culture का मामला है। अपने दम पर code लिखने का बहुत डर होता है, और नतीजा यह कि छोटी-सी चीज़ के लिए भी external dependencies पर भरोसा कर लिया जाता है। hobby projects करने वाले developers में यह डर कम होता है, और कई बार उनका code ज़्यादा robust भी होता है। अगर दिलचस्पी हो, तो अपनी company team से बिना बड़े frameworks के कुछ बनवाकर देखिए, तुरंत समझ आ जाएगा
छोटे-छोटे trivial modules अलग से लेने का एक कारण यह भी है कि client में अनावश्यक code bundle न हो। all-in-one libraries बेहतर DX देती हैं, लेकिन वे अक्सर ऐसा code भी साथ ले आती हैं जिसकी ज़रूरत नहीं होती (tree-shaking है, लेकिन वह भी हर समस्या का समाधान नहीं)
leftpad घटना के बाद से यह बहस लगातार चल रही है। शायद JS standard library बहुत छोटी होने की वजह से भी ऐसा है
code change PR में किसी "trusted" दिखने वाले module की एक लाइन
importजोड़ना, बड़े code change की तुलना में reviewer को कहीं आसान लगता है। असल में यह ज़्यादा सुरक्षित नहीं होता, लेकिन थकान की हालत में यह ज़्यादा भरोसेमंद लगता हैपिछली nx घटना के समय भी मैंने यही बात कही थी: package managers में एक grace period होना चाहिए, जिसमें नए packages को कुछ समय (जैसे 24 घंटे) तक अनिवार्य रूप से skip किया जाए। ज़्यादातर ऐसे attacks release के तुरंत बाद detect और block हो जाते हैं, इसलिए अगर उस अवधि में users latest version अपने आप install न करें, तो वास्तविक नुकसान काफ़ी घट सकता है
मैं कल्पना कर सकता हूँ कि लेखक ने कितना दर्द और stress झेला होगा। सिर्फ़ एक गलती की वजह से बार-बार सफ़ाई देनी पड़े, यह बहुत कठिन होगा। यह घटना यह भी दिखाती है कि open source ecosystem वास्तव में कितनी हद तक एक व्यक्ति के स्वामित्व वाले packages पर निर्भर है। हमें मानना चाहिए कि कोई भी गलती से hack हो सकता है। तकनीकी दृष्टि से देखें तो, जब AI का इतना उपयोग हो रहा है, तब deno/node/bun जैसी जगहों पर suspicious code के लिए warnings दिखनी चाहिए, या Debian-style verification के आधार पर
@verifiedजैसी publishing से trust बढ़ना चाहिए, और latest के बजाय verified versions इस्तेमाल करने जैसी सांस्कृतिक बदलाव की ज़रूरत है। लेखक भी इंसान है, और हम सबको उनके साथ दयालु रहना चाहिए। जब स्थिति संभल जाए, तो मैं इससे जुड़ा और technical detail वाला analysis या postmortem भी पढ़ना चाहूँगा