• Seattle Times ने Shai-Hulud 2.0 हमले से संयोगवश बचाव कर लिया, लेकिन यह मानते हुए कि किस्मत सुरक्षा रणनीति नहीं हो सकती, उसने client-side defense अपनाया
  • npm में Trusted publishing / provenance / granular tokens जैसे सुधार “deployment” पक्ष को मजबूत करते हैं, लेकिन “install·update” के समय malicious code execution को नहीं रोकते — यह एक खाली जगह छोड़ता है
  • pnpm, npm registry को ज्यों का त्यों इस्तेमाल करते हुए भी consumption (install/update) stage पर malicious package execution को कठिन बनाने वाले controls जोड़ता है
  • पायलट में pnpm के 3 controls लागू किए गए ताकि lifecycle script execution, latest release की तुरंत installation, trust downgrade जैसे vectors को अलग-अलग रोका जा सके
  • exceptions को failure नहीं बल्कि design का हिस्सा माना गया, और exceptions को document करते हुए भी बाकी layers सुरक्षा देती रहें — यही defense-in-depth ऑपरेशन का लक्ष्य है

घटना की पृष्ठभूमि और आधार

  • नवंबर 2025 में self-replicating npm worm ने 796 packages को संक्रमित किया और 13.2 करोड़ मासिक downloads के पैमाने पर फैलने का मामला सामने आया
  • हमले में preinstall script का उपयोग कर credentials चोरी किए गए, persistent backdoor install किए गए, और कुछ environments में development environment तक मिटा दिए गए
  • हमारे संगठन पर इसका असर न होने की वजह मजबूत defense नहीं, बल्कि हमले की अवधि में npm install/npm update न चलाया जाना — यानी संयोग — था
  • news organizations के लिए trust सबसे महत्वपूर्ण है, और supply chain compromise से customer data, employee credentials, production infrastructure, source code उजागर हो सकते हैं; recovery और notification की लागत भी बड़ी होती है

टीम और adoption का संदर्भ

  • Seattle Times लंबे समय से npm को default package manager के रूप में इस्तेमाल करता रहा है; Yarn पर प्रयोग हुए लेकिन वे टिक नहीं पाए
  • pnpm अपनाने का कारण registry-level improvements को पूरक client-side security controls हैं
  • pnpm को उसी registry, उसी commands और उसी workflow के साथ इस्तेमाल होने वाला drop-in replacement माना गया, इसलिए migration संभव लगा
  • यह कोई पूरा हो चुका case study नहीं, बल्कि supply chain security पर काम शुरू कर रही एक वास्तविक टीम की समस्याओं और सोच की साझेदारी है

client-side controls क्यों जरूरी हैं

  • npm के security improvements ने account compromise के बाद malicious package publish करना पहले से कठिन जरूर बनाया है
  • ये सुधार “publishing” पक्ष की रक्षा करते हैं, लेकिन “consuming” चरण में malicious package की installation को स्वयं नहीं रोकते
  • npm install/npm update के समय lifecycle scripts (preinstall/postinstall आदि) package safety का मूल्यांकन होने से पहले developer permissions के साथ arbitrary code चला सकते हैं
  • ये scripts npm/GitHub/AWS/DB credentials, source code, cloud infrastructure और पूरे filesystem तक पहुंच सकती हैं
  • Shai-Hulud जैसे हमले इसी संरचना का दुरुपयोग करते हैं; maintainer account compromise होने पर malicious script installation के उसी क्षण चल सकती है, और community द्वारा detect करने से पहले नुकसान हो सकता है
  • npm के publishing-side improvements और pnpm के consuming-side controls को एक-दूसरे का पूरक defense मानकर “defense-in-depth” बनाया गया

लागू की गई 3 layers

  • पायलट में अलग-अलग attack vectors को लक्ष्य बनाने वाले 3 controls साथ में उपयोग किए गए
  • हर control में वास्तविक दुनिया के exceptions के लिए escape hatch है, और design शुरू से इस आधार पर किया गया कि production environment में exceptions की जरूरत पड़ेगी

Control 1: Lifecycle Script Management

  • pnpm डिफॉल्ट रूप से lifecycle scripts को block कर सकता है और installation warning के साथ आगे बढ़ सकती है
  • warning के अनदेखा हो जाने की चिंता के कारण strictDepBuilds: true चुना गया, ताकि script मौजूद होने पर installation तुरंत fail हो
  • configuration उदाहरण pnpm-workspace.yaml में इन fields से बना है
    • strictDepBuilds: true
    • onlyBuiltDependencies: जिन packages में जरूरी build scripts हों, उनकी allow list
    • ignoredBuiltDependencies: जिन packages में अनावश्यक build scripts हों, उनकी block (या ignore) list
  • “जरूरी scripts” से मतलब native extension compile करना, platform-dependent libraries को link करना जैसी क्रियाएं हैं
  • “अनावश्यक scripts” वे हैं जो optimization या optional configuration के लिए हों, और टीम के उपयोग में functionality को प्रभावित न करती हों
  • installation failure के जरिए अगला चरण अनिवार्य किया गया
    • pnpm स्पष्ट रूप से बताता है कि किन packages में scripts हैं
    • script behavior की जांच और समझ
    • मानव निर्णय के आधार पर allow/block का सचेत निर्णय और documentation
  • pnpm टीम v11 में strictDepBuilds: true को default बनाने पर विचार कर रही है, और allow/deny syntax के naming improvement पर भी सोच रही है

Control 2: Release Cooldown

  • हाल ही में publish हुए version को एक निश्चित cooldown अवधि तक install होने से रोका जाता है, ताकि community को malicious package detect और remove करने का समय मिले
  • configuration उदाहरण pnpm-workspace.yaml में इन fields से बना है
    • minimumReleaseAge: <duration-in-minutes>
    • minimumReleaseAgeExclude: emergency hotfix जैसी exceptions की allow list
  • “latest is best” वाली आदत छोड़कर यह सोचना जरूरी है कि supply chain के नज़रिए से थोड़ा पुराना version ज्यादा सुरक्षित हो सकता है
  • सितंबर 2025 के हमले (debug, chalk समेत 16 packages) में removal में लगभग 2.5 घंटे लगे, जबकि नवंबर 2025 के Shai-Hulud 2.0 में लगभग 12 घंटे लगे
  • संगठन की risk tolerance के अनुसार cooldown घंटे/दिन/हफ्ते का हो सकता है, और किसी भी रूप में वह इस तरह के हमले को रोक सकता था
  • यह उस वास्तविकता से मेल खाता है कि संगठन वैसे भी हमेशा बिल्कुल latest version नहीं चला पाते, इसलिए cooldown काम में बड़ी बाधा नहीं बनता
  • security patch या critical bug जैसी जरूरत होने पर review के बाद exception दी जा सकती है

Control 3: Trust Policy

  • अगर कोई version पिछले version की तुलना में कमजोर authentication के साथ publish हुआ हो, तो उसकी installation block कर दी जाती है
  • इसे उस संकेत के रूप में देखा गया है कि maintainer account compromise होने के बाद publish आधिकारिक CI/CD के बजाय attacker machine से किया गया हो सकता है
  • configuration उदाहरण pnpm-workspace.yaml में इन fields से बना है
    • trustPolicy: no-downgrade
    • trustPolicyExclude: CI/CD migration जैसी exceptions की allow list
  • बताया गया है कि npm package publishing के लिए 3 trust levels track करता है (मजबूत→कमजोर)
    • Trusted Publisher: GitHub Actions + OIDC + npm provenance आधारित
    • Provenance: CI/CD में signed attestation
    • No Trust Evidence: username/password या token-based publishing
  • नया version अगर पिछले version से कम trust level दिखाता है, तो installation fail हो जाती है
  • अगस्त 2025 के s1ngularity हमले में attacker ने CI/CD access के बिना local machine से malicious version publish किया था और provenance नहीं था; उस मामले में यह control installation रोक देता
  • वैध downgrade के उदाहरणों में नया maintainer जुड़ना, CI/CD migration, या CI/CD outage के दौरान manual hotfix शामिल हैं; जांच के बाद इन्हें exception list में जोड़ा जा सकता है
  • यह feature नवंबर 2025 में pnpm में जोड़ा गया नया feature है, और वैध downgrade वास्तव में कितनी बार होते हैं, यह अभी सीखा जा रहा है

layer combination का उदाहरण: React vulnerability patch

  • दिसंबर 2025 में घोषित React Server Components की critical vulnerability का patch तुरंत लागू करना पड़े, ऐसी स्थिति में
  • सामान्यतः cooldown “अभी-अभी publish हुए version की installation” रोकता है, लेकिन critical security patch के लिए इंतजार नहीं किया जा सकता
  • ऐसे में minimumReleaseAgeExclude में विशेष React version जोड़ा जा सकता है, लेकिन vulnerability announcement और patch की वैधता की समीक्षा के बाद ही exception लागू की जाएगी
  • exception लागू होने पर भी दूसरी layers सुरक्षा देती रहती हैं
    • React में सामान्यतः lifecycle scripts नहीं होतीं; इसलिए patch version में script आ जाए तो वह तुरंत संदेह का संकेत बनेगी और block हो सकती है
    • अगर attacker credentials चुराकर local machine से “patch” publish करे, तो trust level downgrade के कारण block किया जा सकता है
  • exception को “security failure” नहीं, बल्कि ऐसा design माना गया जिसमें एक layer bypass होने पर भी दूसरी layers बची रहती हैं और single point of failure खत्म हो जाता है

पायलट के नतीजे

  • एक backend service पर तीनों controls लागू कर PoC चलाया गया
  • जांच, समझ और access definition तक पहुंचने में कुल तैयारी समय कुछ घंटों का था
  • pnpm ने lifecycle scripts वाले 3 packages की पहचान की
    • esbuild: CLI startup को millisecond स्तर पर optimize करता है, लेकिन टीम केवल JS API इस्तेमाल करती है, इसलिए इसे अनावश्यक माना गया
    • @firebase/util: client SDK auto-configuration के लिए है, लेकिन टीम केवल server SDK इस्तेमाल करती है, इसलिए इसे अनावश्यक माना गया
    • protobufjs: schema compatibility check के लिए है, लेकिन यह केवल transitive dependency के रूप में उपयोग होता है और टीम के use case में अनावश्यक था
  • documentation की जांच और script analysis (जिसमें AI द्वारा script interpretation की सहायता भी शामिल थी) के बाद निष्कर्ष निकला कि ये तीनों scripts टीम के उपयोग में आवश्यक नहीं थीं, इसलिए इन्हें block किया गया
  • functionality पर कोई असर नहीं पड़ा
  • friction को एक जानबूझकर जोड़ा गया feature माना गया, क्योंकि यह environment में चलने वाले code पर implicit trust को खत्म करने वाला enforcement mechanism है
  • अगर किसी नई dependency में script हो, तो उसकी review और documentation में लगभग 15 मिनट लगने की उम्मीद है

संचालन से मिली सीख

  • client-side layers और npm के publishing-side improvements का संयोजन defense-in-depth को व्यवहार में काम करते हुए दिखाता है
  • exceptions लागू होने पर भी दूसरी layers मौजूद रहती हैं, इसलिए exceptions को लेकर चिंता कम होती है
  • “convenience first” से “security first” की mental model shift में समय लगता है, लेकिन आदत बन जाने पर यह स्वाभाविक लगता है
  • dedicated security team न होने वाले mid-sized organizations में भी इसे व्यावहारिक रूप से लागू किया जा सकता है
  • trust policy अभी कुछ ही हफ्ते पुराना feature है, इसलिए वैध downgrade की आवृत्ति और operational feel के बारे में अभी और सीखना बाकी है
  • निकट भविष्य में इसे दूसरे codebases तक बढ़ाने की योजना है, और अलग dependency graphs वाले applications से अधिक data मिलेगा

दूसरी टीमों के लिए लागू करने के सुझाव

  • पहले एक project से शुरुआत कर workflow और friction points को समझने की सलाह दी गई है
  • lifecycle scripts, release cooldown और trust downgrade — तीनों में exceptions की जरूरत पड़ सकती है, इसलिए शुरुआत से exceptions को design assumption मानें
  • warning-based approach की बजाय installation failure लागू करने वाली strictDepBuilds: true रणनीति पहले दिन से अपनाने की सिफारिश है
  • सभी exceptions को document करें, ताकि audit trail रहे और बाद में सफाई/समायोजन आसान हो
  • याद रखें कि एक layer में exception देने पर भी दूसरी layers की सुरक्षा बनी रहती है

अभी कोई टिप्पणी नहीं है.

अभी कोई टिप्पणी नहीं है.