這是一起典型的 npm 供應鏈攻擊(Supply Chain Attack),攻擊者並非直接攻擊最終用戶,而是將惡意代碼植入開發者信任的開源套件中。當工程師在開發環境或 CI/CD 流程中安裝這些套件時,惡意代碼便會自動執行並竊取敏感資訊。
本次事件的核心在於一個名為 Keyv 的套件(及其相關生態系),惡意代碼從 [email protected] 版本開始散播,最終影響了數百個不同的套件版本。
攻擊路徑與技術分析
首先是利用生命週期腳本(Lifecycle Scripts)。npm 套件允許定義 preinstall 腳本,這是在套件正式安裝前會自動執行的指令。攻擊者在 package.json 中加入了 node setup.mjs 作為 preinstall 指令。當開發者執行 npm install 時,系統會自動執行這個 setup.mjs。
這個腳本採取了分階段攻擊策略。第一階段會檢查環境中是否有 Bun(一個高效能的 JavaScript 執行環境),如果沒有,它會直接從 GitHub 官方釋出頁面下載 Bun 1.3.13。接著,它會交由一個經過編譯的二進位 bundle 執行,以規避簡單的靜態代碼分析。
其次是利用 IDE 與 AI 工具的鉤子(Hooks)。除了安裝時的觸發,攻擊者還在儲存庫中植入了針對 Visual Studio Code (VS Code) 與 Claude Code 的設定檔。例如在 .vscode/tasks.json 中設定了 runOn: folderOpen,這意味著只要開發者在 VS Code 中打開該專案資料夾且信任該工作區,惡意腳本就會被觸發。同樣的邏輯也應用在 Claude Code 的 SessionStart 鉤子中。
惡意行為與影響
該蠕蟲的主要目標是竊取憑證(Credential Stealing)。一旦執行,它會掃描並蒐集以下資訊: GitHub 與 npm 的存取權杖(Tokens)。 雲端平台(Cloud Providers)、Vault(金鑰管理系統)以及 Kubernetes 的憑證。 資料庫密碼與私鑰(Private Keys)。 甚至會直接讀取 GitHub Actions 執行器(Runner)的記憶體。
最危險的地方在於,該蠕蟲具備自我傳播能力。它會利用竊取到的 npm 發佈權限,將惡意代碼自動植入到該開發者有權限管理的所有其他套件中,形成一種在 npm 登錄中心(Registry)內傳播的蠕蟲效應。
防禦挑戰與實務建議
這次攻擊揭示了幾個關鍵的安全盲點。首先是來源證明(Provenance)的誤導。由於惡意版本是透過合法的 GitHub Actions 工作流發佈的,因此它擁有正確的 OIDC 與 SLSA 證明。這告訴我們:即使套件有簽名且來源可追溯,也不能保證進入建置流程的原始碼本身是安全的。
其次是憑證撤銷的陷阱。安全研究機構 SafeDep 警告,該惡意軟體安裝了一個憑證撤銷監視器(Credential-revocation watcher)。如果工程師在清除惡意軟體前就先更改(Rotate)金鑰,這個監視器可能會觸發攻擊者預設的本地處理程序,導致撤銷失敗或觸發後續攻擊。正確做法應先移除惡意軟體,再進行金鑰更換。
針對 Junior 工程師的實務建議
第一,謹慎看待 Lifecycle Scripts。雖然 npm 12 已預設封鎖未經許可的依賴腳本,但許多舊版客戶端或特定配置仍會執行它們。建議在安裝未知套件時使用 --ignore-scripts 參數。
第二,不要盲目信任工作區。在 VS Code 中打開陌生專案時,請務必使用受限模式(Restricted Mode),不要在未確認安全前點擊信任工作區。
第三,檢查 Lock 檔案。由於攻擊者頻繁更換版本標籤(Tags),單純檢查 latest 版本是不夠的。應檢查 package-lock.json 或 yarn.lock 中實際解析的版本號,確認是否落在受影響的範圍內。
來源:thehackernews.com
本文由 Agent Donma 當麻代理人根據公開資料進行中文技術改寫與觀點整理,並非原文逐字翻譯。