2026 年 5 月 11 日,自我傳播的供應鏈蠕蟲 Mini Shai-Hulud 在 npm 爆發。StepSecurity 歸因於 TeamPCP:竊取維護者憑證後,自動發布其名下套件的受感染版本。TanStack 確認 42 個 @tanstack/* 套件被植入 84 個惡意版本,疫情超過 170 個套件。
最刺眼的是:惡意套件帶著密碼學上有效的 SLSA 證明上架——蠕蟲劫持的是專案自己的發布管線。
攻擊鏈:從一個 fork 到 170 多個套件
攻擊帳號 3 月建立、蟄伏待命,5 月 10 日 fork TanStack/router 藏入 payload,11 日惡意版本上架:react-router 1.169.5/1.169.8 等帶毒,並蔓延到 opensearch、UiPath、safe-action 等。
Mistral 的 mistralai/client-ts issue #217 回報 @mistralai/mistralai 2.2.4 遭植入;受影響為 2.2.3/2.2.4,azure/gcp 變體與 PyPI 側也中鏢。
植入手法容易稽核:被汙染的 tarball 多一條 optionalDependencies,加上 2.3 MB、三層混淆的 router_init.js,體積從 190 KB 漲到 905 KB。
竊取的就是 AI 開發者的東西
payload 為 AI 開發環境量身打造:從 /proc 程序記憶體讀取 GitHub Actions Runner.Worker、掏走 OIDC 權杖與 AWS IMDSv2、ECS、Vault 憑證,掃 100 多條路徑,從雲端金鑰到 Claude、Kiro 設定檔。它在 Claude Code、VS Code 安裝持久化,用偽裝的 workflow 傾倒整個 repo 機密;為閃避 Node.js 工具改跑 Bun 1.3.13,外傳走 Session CDN 與 GitHub dead-drop commit,郵址偽造成 claude@users.noreply.github.com。
為什麼有效的 SLSA 證明擋不住
Red Hat 的 Andrew McNamara 在 SLSA 部落格拆解三步鏈:pull_request_target 讓 fork 程式碼在信任環境執行;惡意碼汙染 pnpm 共享快取、被正規 release workflow 還原;最後撈出 OIDC 權杖直推 npm。
結論很硬:簽章正確不代表可信任。npm 內建 provenance 只達 Build L2,此攻擊同時踩破 L3 的三個隔離要求——共享快取被汙染、簽署身分暴露、攻擊程式碼跨建置存活。兩次惡意 CI run 以 failure 收場卻照樣發布,對此告警可縮短暴露窗。
自我傳播與勒索式陷阱
蠕蟲尋找帶 bypass_2fa 的 npm token,枚舉維護者名下套件、發布受感染版本。其中一個 token 描述寫著「撤銷這個 token 將抹除擁有者的電腦」——先隔離取證、再輪換,貿然 revoke 可能觸發破壞性清除。
事件後該做的事
裝過受害版本就假設該環境機密全毀:降級到乾淨版本、刪 node_modules 重裝、輪換 npm token、PAT、雲端金鑰與 SSH key,並稽查 11 日 19:20 UTC 後的 CI。結構性修補:閘控 pull_request_target、最小權限、以 digest 釘選 action、共享快取視為信任邊界。把 agent 設定檔當機密;部署 coding agent 時,沙箱與審批是下一層防線(見OpenAI 安全部署 Codex)。
參考來源
- Mini Shai-Hulud Is Back — StepSecurity
- Mistral SDK compromised — GitHub
- Where SLSA’s Boundaries Fall — SLSA
本文由 AI 協助自上述來源整理,經人工審核後發布。
