NPM में 86,000 से अधिक बार डाउनलोड किए गए malicious packages का बड़े पैमाने पर प्रसार
(arstechnica.com)- यह पुष्टि हुई है कि NPM repository में credentials चुराने के लिए 100 से अधिक malicious packages अगस्त के बाद बिना detect हुए upload किए गए और उन्हें कुल 86,000 से अधिक बार डाउनलोड किया गया
- security company Koi ने रिपोर्ट किया कि 'PhantomRaven' नाम का attack campaign, NPM के Remote Dynamic Dependencies(RDD) feature का दुरुपयोग करके 126 malicious packages फैलाने में इस्तेमाल किया गया
- RDD ऐसी संरचना है जो package को untrusted domains से dependency code dynamically डाउनलोड करने देती है, इसलिए इसे static analysis tools detect नहीं कर पाते
- attackers ने इस feature का उपयोग HTTP connection के जरिए malicious code डाउनलोड करने के लिए किया, लेकिन package metadata में यह “0 Dependencies” के रूप में दिखा, जिससे developers और security scanners इसे पहचान नहीं पाए
- यह structural weakness NPM ecosystem की security management limits और automatic installation mechanism के जोखिम को उजागर करती है
NPM repository में malicious packages का प्रसार
- attackers ने NPM code repository की structural weakness का फायदा उठाकर अगस्त के बाद credentials चुराने वाले 100 से अधिक packages upload किए
- अधिकांश packages बिना detect हुए वितरित हुए, और इनका cumulative download count 86,000 से अधिक रहा
- security company Koi ने इस attack को PhantomRaven campaign नाम दिया और विश्लेषण किया कि NPM के एक specific feature का दुरुपयोग किया गया
- Koi के अनुसार, 126 malicious packages में से लगभग 80 article लिखे जाने के समय तक भी NPM पर मौजूद थे
Remote Dynamic Dependencies(RDD) की कमजोर संरचना
- RDD एक ऐसा feature है जो package को external website से dependency code dynamically डाउनलोड करने की अनुमति देता है
- आम तौर पर dependencies, NPM की trusted infrastructure से डाउनलोड होती हैं, लेकिन RDD HTTP जैसे unencrypted connections के जरिए डाउनलोड की भी अनुमति देता है
- PhantomRaven attackers ने इस feature का उपयोग code को malicious URL (उदाहरण:
http://packages.storeartifact.com/npm/unused-imports) से डाउनलोड कराने के लिए configure किया- ऐसी dependencies developers और security scanners को दिखाई नहीं देतीं, और package information में “0 Dependencies” के रूप में दिखती हैं
- NPM के automatic installation feature के कारण ऐसे 'अदृश्य' dependency code अपने आप execute हो जाते हैं
security tools की detection limitations
- Koi के Oren Yomtov ने कहा, “PhantomRaven मौजूदा security tools के blind spot का बेहद परिष्कृत तरीके से दुरुपयोग करने का उदाहरण है”
- RDD को static analysis tools detect नहीं कर पाते
- इसके कारण attackers security validation को bypass करते हुए malicious code वितरित कर सके
अतिरिक्त कमजोर कारक
- Koi ने बताया कि RDD से डाउनलोड की गई dependencies हर installation पर attacker server से दोबारा डाउनलोड होती हैं
- cache या version management न होने के कारण, एक ही package में भी installation के समय के अनुसार अलग malicious code inject होने की संभावना रहती है
- ऐसी dynamic download संरचना package integrity verification को कठिन बनाती है
NPM की संरचना और पृष्ठभूमि
- NPM JavaScript के लिए package manager है, जिसे GitHub की subsidiary npm, Inc. manage करती है
- यह Node.js का default package manager है और command-line client तथा npm registry से मिलकर बना है
- registry में public और paid private packages store होते हैं, और website के जरिए उन्हें खोजा जा सकता है
- इस घटना को ऐसे उदाहरण के रूप में देखा जा रहा है जो दिखाती है कि NPM की automatic dependency management संरचना हमलों में दुरुपयोग की जा सकती है
अन्य उल्लेख
- लेख के अंत में अनावश्यक JavaScript execution को block करने की आवश्यकता का उल्लेख है
- हालांकि, यह भी रेखांकित किया गया कि इस बार ज़रूरी JavaScript code तक का दुरुपयोग किया गया
2 टिप्पणियां
मैंने एक रीयल-टाइम स्कैनर स्क्रिप्ट बनाई है.
संदिग्ध repository के path में
npx sha1-hulud-scannerदर्ज करें.
सोर्स कोड : https://github.com/developerjhp/sha1-hulud-scanner
Hacker News राय
आजकल मैं
npmकमांड को Docker container के अंदर चलाने के लिए alias सेट करके रखता हूँऐसा करने से मेरे environment variables expose नहीं होते, current directory के बाहर की files तक access नहीं मिलता, और
.bashrcजैसी config files तक भी पहुँच नहीं हो पातीसंदर्भ: Run tools inside Docker
npmऐसा arbitrary code डाउनलोड करता है जो तुरंत चल सकता हैइसकी जगह
pnpmबेहतर है। यह default रूप से lifecycle scripts नहीं चलाता, और जिन scripts को allow करना हो उन्हें whitelist किया जा सकता हैअगर सच में सुरक्षा चाहिए, तो सिर्फ install नहीं बल्कि पूरे execution को sandbox के अंदर चलाना होगा
अभी की तरह सिर्फ post-install रोकना आधा-अधूरा उपाय है। supply chain attacks लगातार ज़्यादा खतरनाक होते जा रहे हैं
अगर
neovimयाvscodeसंक्रमित हो जाए, तो user privileges के साथ ही काफी खतरनाक काम किए जा सकते हैंसाधारण alias
node/npmपर तो काम करता है, लेकिन दूसरे programs पर लागू करना कठिन है। क्योंकि container में ज़रूरी resources mount करने पड़ते हैंमैं लंबे समय से सोचता रहा हूँ कि लोग इतनी आसानी से
npmको सिस्टम पर क्यों चलाते हैंmakeजैसे reproducible build के आदी नज़रिए से देखें, तोnpmका हर बार कुछ अलग डाउनलोड करना और अलग परिणाम देना चौंकाने वाला थाCSS generation तक को npm dependencies से बाँध देना अजीब लगा। इसलिए मैंने Docker के अंदर पूरे npm environment को freeze करने की कोशिश की, लेकिन अंत में यह हारी हुई लड़ाई जैसा लगा
maven,nuget,pip,npmसब ऐसे ही हैंअगर हम पहले की तरह सिर्फ distro package managers पर निर्भर रहते, तो आज जैसा तेज़ ecosystem संभव नहीं होता
हाँ, security को मज़बूत करने वाले नए package managers आ रहे हैं। वजह समझे बिना सिर्फ माध्यम को दोष देना सही नहीं है
npmको Docker में freeze किया था, तो मैं पूछना चाहूँगा कि dependency update के बाद क्या आप हर बार उस environment को verify करते थेदरअसल
npmऔरpnpmपहले से ही default रूप में lock files के जरिए dependencies को pin करते हैंnpm install thing” बहुत आसान और सस्ता हैबहुत-सा open source quality से ज़्यादा resume-driven code से भर जाता है, और आखिरकार वही किसी बड़ी कंपनी के ad tracker या wallet app जैसी चीज़ों में इस्तेमाल होता है
npm installसिर्फ package डाउनलोड नहीं करता, बल्कि code execute करता हैpackage.jsonके preinstall, install, postinstall hooks सचमुच चलाए जाते हैंinstall प्रक्रिया के दौरान वैध रूप से arbitrary commands चलाने की ज़रूरत आखिर क्यों होनी चाहिए?
संबंधित रिपोर्ट: PhantomRaven npm malware
एक और मामला: Socket.dev ब्लॉग
उदाहरण के लिए Linux kernel package install होने के बाद initramfs को दोबारा बनाना, GRUB update करना जैसी चीज़ों के लिए post-install scripts चलाता है
ज़्यादातर DEB/RPM packages में ऐसे scripts शामिल होते हैं। यानी यह design का ही मसला है
npmमें कोई भी package publish कर सकता हैLinux distributions में भरोसेमंद maintainer system होता है, और कई बार PGP-आधारित root of trust भी बनाया जाता है
जबकि
npm,pip,rubygems,cargoवगैरह असल में “curl | bash” का ही एक polished version हैंmaintenance burden घटाने के लिए ऐसे post-install build की ज़रूरत पड़ी
Package.swiftfile को वास्तव में execute करता हैलेकिन सुना है कि यह काफ़ी मज़बूती से sandboxed होता है, इसलिए दुरुपयोग कठिन है
संदर्भ: SwiftPM docs, PackageDescription
pnpm v10default रूप से सभी lifecycle scripts को disable करता है, और user को उन्हें manually allow करना पड़ता हैसंबंधित चर्चा
हाल के
npmattacks को देखकर लगता है कि अबnpmके साथ development करना सुरक्षित है भी या नहींहर बार जब React project शुरू करता हूँ, सैकड़ों packages install हो जाते हैं, और पता ही नहीं चलता कि वे क्या कर रहे हैं
backend में तो ज़रूरत के packages ही explicitly install करता हूँ, लेकिन frontend vulnerabilities का Pandora’s box जैसा लगता है
npmसबसे बड़ा है और खबरों में ज़्यादा आता हैjjinstall किया तो 470 packages आए, और Python केwan2gpमें 211 packages। सब जगह लगभग वही हाल हैxzघटना की तरह, हर dependency किसी random individual पर टिकी होती है, और हमें भरोसा करना पड़ता है कि वे social engineering attack का शिकार नहीं होंगेPyPIभी सुरक्षित नहीं है। GitHub Actions hack के जरिए legitimate package में malicious code डालने के मामले भी सामने आए हैंAngular, Vue जैसे frameworks के साथ development करते समय हर बार घबराहट होती है
node_modulesके अंदर हज़ारों dependencies देखकर यह आने वाली तबाही जैसा लगता हैकोई एक open source developer phishing का शिकार हो जाए तो तुरंत infection हो सकता है
JavaScript ecosystem मूल रूप से टूटा हुआ है। सिर्फ एक typo से supply chain attack के सामने आ सकते हैं
NuGet या Maven में भी यह संभव है, लेकिन वहाँ standard library बड़ी होती है, इसलिए dependencies कम रहती हैं और कुछ नियंत्रण का एहसास होता है
यह परफेक्ट नहीं है, लेकिन फिर भी एक स्तर बेहतर है
86,000 downloads में से ज़्यादातर असली users नहीं, बल्कि automated scanners या bots होने की संभावना है
नई version publish करते ही एक-दो दिन में सैकड़ों downloads दिखते हैं, लेकिन वे असली इंसान न भी हों
यानी संक्रमित users की संख्या बहुत कम, या शायद लगभग शून्य भी हो सकती है
AI chatbots द्वारा hallucination से बनाए गए package names को निशाना बनाने वाले attacks भी बहुत हैं। यह सिर्फ साधारण आँकड़ों की बात नहीं है
हमले का और विस्तृत विवरण BleepingComputer लेख में देखा जा सकता है
मैं सोच रहा हूँ कि
npm installके दौरान HTTP URL को dependency की तरह इस्तेमाल करने वाले packages को detect या filter करने का कोई तरीका है या नहींक्योंकि requester के हिसाब से अलग payload भेजा जा सकता है, इसलिए सामान्य scanners के लिए इसे पकड़ना कठिन है
एक hobby developer के रूप में मैं सोचता हूँ कि ऐसे supply chain attacks से बचाव कैसे किया जाए
मशहूर tutorials को follow करते हुए dependencies install करते-करते कब security के प्रति लापरवाह हो जाते हैं, पता ही नहीं चलता
मैं अपने homelab में कई services भी चलाता हूँ, और चिंता रहती है कि कहीं कोई bot घुसपैठ न कर ले। शुरुआत कहाँ से करूँ?
यह पूरी गारंटी नहीं है, लेकिन पूरे server के compromise होने से कहीं बेहतर है
ज़रूरत का code खुद कॉपी करके इस्तेमाल करना भी सीखने और सुरक्षित रहने का अच्छा तरीका है
ऐसे ढाँचे में लाखों users को अलग-अलग verify करने की ज़रूरत नहीं पड़ती, क्योंकि distribution स्तर पर भरोसेमंदी सुनिश्चित की जा सकती है
उदाहरण: Hono, Zod
मैं हाल ही में Bun पर switch हुआ हूँ, क्योंकि इसमें DB driver या S3 client जैसी चीज़ें default रूप से built-in मिलती हैं, जिससे अतिरिक्त downloads कम हो जाते हैं
lifecycle hooks के अंदर dependencies लाने वाली संरचना कभी भी attack pivot point बन सकती है
आज भले वह सामान्य हो, लेकिन बाद में owner hack हो जाए या उसका इरादा बदल जाए, तो वही malicious code बन सकता है
इस तरह के install hooks आखिरकार टिकाऊ design नहीं हैं