編按:本文綜合整理自 Aikido Security 原始通報、Snyk 技術分析與 Datadog Security Labs 追蹤報告,並加入 Siami 編輯部觀點與數據解讀。
上億下載的 Keyv 發布路徑遭接管
2026 年 8 月 4 日,資安公司 Aikido Security 通報,JavaScript 鍵值儲存函式庫 Keyv 的維護者 GitHub 帳號或發布路徑遭到入侵。攻擊者把竊密程式直接推進專案主分支,隨即透過原本合法的 GitHub Actions 流程發布新版本,讓惡意套件仍帶有有效的來源證明與建置簽章。
Keyv 並非冷門小套件。Aikido 在事件初期估計它每週約有 1.27 億次下載;npm 後續頁面顯示的週下載量甚至超過 1.5 億。更麻煩的是,同一維護者還管理多個廣泛使用的快取工具,包含 cacheable、flat-cache、file-entry-cache、cache-manager 與 cacheable-request。這些套件常透過 ESLint 等開發工具進入專案,即使開發者沒有主動安裝 Keyv,也可能因間接相依而受影響。
這次惡意版本不是等待應用程式呼叫某個漏洞,而是在 package.json 加入:
preinstall: node setup.mjs- 29,918 位元組的
setup.mjs載入器 - 727,680 位元組的第二階段檔案
Math_Symbol.js - 指向 VS Code 與 Claude Code 專案設定的額外執行機制
因此,只要受污染版本在開發者電腦或 CI runner 上執行 npm install、npm ci,惡意程式就可能在應用程式啟動以前執行;是否曾 import keyv 並不是判斷安全與否的標準。
惡意版本與已知攻擊能力
Snyk Security Research 直接從 npm registry 下載並比較套件檔案,確認至少 11 個惡意版本帶有相同載入器與第二階段檔案。初期名單包括:
[email protected]@cacheable/[email protected]@cacheable/[email protected][email protected][email protected]@cacheable/[email protected][email protected][email protected]@cacheable/[email protected][email protected][email protected]
Datadog 的後續追蹤則指出,活動已蔓延至數百個 npm 套件。不同研究團隊的統計口徑與快照時間不同,數字仍在快速變化;可靠做法不是只記住一份靜態名單,而是檢查 lockfile、私有套件鏡像與 CI 安裝紀錄。
依 Datadog 分析,惡意程式會掃描本機檔案、環境變數、CI runner 與雲端中繼資料服務,目標包括:
- npm 發布 token 與
.npmrc內的認證資料。 - GitHub PAT、GitHub CLI session 與 Actions OIDC token。
- AWS、GCP、Azure 雲端憑證。
- HashiCorp Vault token 與 Kubernetes service-account token。
- 私鑰、資料庫連線字串及 CI 工作可讀取的其他祕密。
取得 npm 發布權限後,蠕蟲還會枚舉受害維護者可發布的其他套件,重新打包並加入惡意安裝 hook,再把污染版本發布出去。這種自我傳播機制,正是研究團隊把事件歸入 Shai-Hulud 家族的重要原因。
有效 provenance 為何沒有擋住惡意版本
這起事件最值得開發團隊警惕的地方,是 [email protected] 擁有由 GitHub Actions 產生的有效 npm provenance。簽章沒有被偽造;發布流程確實來自專案設定的正式工作流程,但進入工作流程的原始碼已被攻擊者污染。
Provenance 能證明「這個產物由哪套流程、哪份來源建置」,卻不能單獨證明「那份來源沒有被已授權帳號或受害工作流程植入惡意內容」。
換句話說,供應鏈驗證不能只看綠色勾勾。當維護者身分、主分支或 release workflow 已經失守,合法流程反而會替惡意產物提供可信外觀。安全審查仍需搭配版本差異、生命週期 script、異常新增檔案、發布時間與維護者行為分析。
Snyk 比較候選版本後發現,受污染的穩定版與先前 release candidate 的正常程式碼幾乎一致,差異主要集中在 preinstall 及兩個惡意檔案。套件安裝後仍能正常工作,這也降低了使用者立即察覺異常的機會。
為什麼這件事重要
這不只是 Keyv 使用者的單一套件事故,而是現代軟體開發「信任預設值」的壓力測試。前端與 Node.js 專案往往包含數百到數千個間接相依,開發者很難逐一認識每位維護者;CI 又習慣在握有部署、雲端與套件發布憑證的環境中自動安裝最新版相依。攻擊者只要接管一個位於依賴樹上游的發布身分,就能把合法套件管理器變成跨組織投遞器。
對台灣與華文開發團隊而言,這次事件的實際提醒不是「不要使用開源」,而是把套件安裝視為可執行外部程式的高權限動作。企業應建立版本冷卻期、精確 lockfile、受控 registry、CI 最小權限及生命週期 script allowlist;個人開發者也應避免在放有長效雲端金鑰的工作站上任意刪除 lockfile 後重新安裝最新版本。
此外,攻擊者加入 .vscode/tasks.json 與 .claude/settings.json,代表 AI 編碼代理與 IDE 工作區已成為新的持久化介面。只檢查 node_modules 已不夠,專案層級的自動命令、agent hooks 與工作區信任設定都應納入事件調查。
數據解讀:下載量不等於受害主機數
Aikido、Snyk、Datadog 與 Socket 公布的下載量、受污染套件數並不完全相同。原因包括統計時間不同、週下載與月下載混用、同一專案重複下載,以及惡意版本只在短時間內位於 latest 標籤。Snyk 統計 7 月 5 日至 8 月 3 日期間,keyv、flat-cache、file-entry-cache 各有約 5.7 億至 6.2 億次下載,但三者經常出現在同一條依賴鏈,不能相加後宣稱等量設備遭入侵。
因此,「1.5 億週下載」代表的是潛在觸及面與上游影響力,不是已證實的受害者數。現階段也沒有經公開驗證的第二階段成功執行或憑證外洩總數。文章採用保守表述:正式 registry 確實發布過惡意版本、部分版本曾位於 latest、蠕蟲確實能擴散,但每個組織是否中招仍須由 lockfile、套件快取、CI 時間線與主機跡證判定。
下載量也不能取代版本檢查。[email protected] 在 Snyk 快照中是已知乾淨的穩定版,而 [email protected] 是已確認污染版本;同一套件名稱下的風險完全不同。安全團隊應保存精確版本與 integrity hash,不要只在資產清單標記「使用 Keyv」。
立即檢查與處置建議
尚未確認是否安裝過惡意版本的團隊,可先從以下順序著手:
- 檢查
package-lock.json、pnpm-lock.yaml、yarn.lock與 CI 紀錄,搜尋上述 11 個版本。 - 盤點私有 registry、代理快取與開發者 npm cache;上游刪版不會自動移除內部副本。
- 搜尋
setup.mjs、Math_Symbol.js、math_init.js,並檢查.vscode/tasks.json、.claude/settings.json與異常 GitHub Actions workflow。 - 若惡意版本曾執行,先隔離主機、保存鑑識資料並移除
gh-token-monitor等持久化機制。 - 從已知乾淨的系統輪替 GitHub、npm、雲端、Vault、Kubernetes、資料庫與部署憑證,並查核異常套件發布與 repository 變更。
- 暫時鎖定 Snyk 核對過的舊版,例如
[email protected]、[email protected]與[email protected],再以--ignore-scripts重建 lockfile。
Snyk 特別提醒,若偵測到 token 監控型持久化程式,應先依事件應變流程停用並保留證據,再撤銷憑證。若直接輪替 token,可能觸發攻擊者預設的處理程序。這項順序涉及正在演變的惡意程式能力,組織應由資安或事件應變人員執行,不宜只靠一般清理腳本。
後續值得追蹤
這起事件仍在發展中,套件名單、移除狀態與歸因都可能更新。目前公開證據支持「Keyv 相關發布路徑遭入侵」與「惡意程式具有 Shai-Hulud 類似能力」,但尚不足以確定幕後操作者身分,也不應把受害維護者當成攻擊者。
後續觀察重點包括:npm 與 GitHub 是否發布正式事故說明、維護者如何重建可信發布鏈、私有 registry 是否持續保存污染 tarball,以及生態系能否把生命週期 script 從預設執行改為明確授權。對開發團隊而言,最重要的行動不是等待完整歸因,而是先確認精確版本、安裝時間與當時可被讀取的憑證範圍。
延伸資料可參考 Keyv 官方 GitHub repository、npm 版本頁與 Datadog 動態追蹤。
網友熱門留言 (3)