一幅生成式抽象插圖,背景為深藍色:一串相互扣合的半透明方塊由左至右排列,每個方塊上都蓋有一個發出微光的青色印記。在鏈條接近中央處,其中一個方塊被換成了深色方塊,上面帶著一模一樣的青色印記,而鏈條越过它繼續延伸,毫無中斷。細細的琥珀色絲線從那個深色方塊向下分岔,通向畫面底部一小排深色終端窗格。圖中沒有出現任何文字、數字、人物、品牌標誌或組織標誌。OrcaRouter 標誌則合成於右下角。
AI Safety Incidents

ChainDrop:400+ 個 npm 套件具備有效來源證明,以及無需 npm install 的 Claude Code hooks

作者

Elias Hawthorne

發佈日期

最新模型 · 20查看全部模型 →
基準測試:Artificial Analysis · 每日更新
返回全部文章

在2026年8月4日,攻擊者接管了keyv 背後的 GitHub 帳號。Elastic Security Labs 表示,這是一款快取函式庫,上個月下載次數超過 6 億次。Wiz Research 與 Orca Security 都記錄到,惡意檔案被直接推送至 keyv 的主分支,隨後該專案自身的 GitHub Actions 工作流程建置並發布了遭汙染的版本——因此它進入 npm 時帶有有效來源證明,也就是供應鏈證明工具用來判定套件是否可信的認證機制。研究人員稱為ChainDrop 的自我傳播蠕蟲,接著利用竊取的 npm 權杖,在其他維護者的套件上如法炮製:Elastic 統計到 8 月 6 日已有超過 400 個不重複套件,Microsoft Threat Intelligence 於 8 月 4 日描述了同一場行動,而新加坡網路安全局則統計到超過 1,300 個遭入侵的套件版本,合計每月下載量達 20 億次。Elastic 與 Microsoft 都描述了會在Claude Code或Visual Studio Code 中開啟儲存庫時重新執行的鉤子。該紀錄的完整來源清單、嚴重度評級與信心評估,收錄於AI 事件檔案庫,並與同期歸檔的其他 npm 及開發者工具供應鏈條目並列。

合法的發布流程如何簽署了自身的淪陷

Wiz Research 還原了事件最初的幾分鐘:從8 月 4 日 09:00 UTC,攻擊者利用一個遭入侵的身分,將 IDE 持久化載荷引入 keyv 儲存庫,隨後不久便發布了包含該載荷的新版 keyv。Wiz 指稱遭入侵的一方為一個 GitHub 維護者帳號,並表示 keyv 與 cacheable 生態系統中的多個套件也接連受到影響。

Orca Security 的快速回應報告對簽章路徑說明得更具體。報告指出,攻擊者將兩個惡意檔案——setup.mjs 與 Math_Symbol.js——直接推送到主分支,並立即發布新版本。由於這些版本是透過遭入侵帳號的 GitHub Actions 工作流程建置,遭汙染的版本便以有效的來源證明簽章發布至 npm,繞過了標準的供應鏈完整性檢查。Zscaler ThreatLabz 是一個未列入該紀錄引用來源的獨立研究團隊,也得出相同結論,並進一步給出等級判定:惡意的 keyv 6.0.0帶有有效的 SLSA Build Level 3來源證明,因為攻擊者控制了來源儲存庫。BleepingComputer 當天報導了這波活動,也記錄了相同機制——惡意檔案被直接推送到各專案的主分支、產生新版本、具有有效來源證明,因為建置是透過合法的 GitHub Actions 工作流程執行。

微軟的分析補充了一個看似矛盾、實則不然的細節。在該蠕蟲的傳播階段,Microsoft Threat Intelligence 發現許多惡意版本 沒有對應的原始碼提交、提取要求、標籤或合法發布,這表示攻擊者直接修改並發布套件 tarball,而非入侵每個公開原始碼儲存庫。綜合來看,這些來源描述了同一場活動中的兩種簽署機制:最初的 keyv 發布版本經過受害者真實的 CI 流程,並帶有為其背書的證明;而該蠕蟲後續的發布版本大多是用竊取的套件註冊表權杖組裝並發布,完全沒有留下原始碼痕跡。微軟自身的觀察是,這種直接發布 tarball 的模式說明了為何惡意版本經常以普通的修補版本號遞增形式出現,卻沒有對應的原始碼提交或提取要求。

令人不安的教訓,Zscaler 說得很明白:出處驗證所驗證的是建置流程,而非帳號的身分,也不是執行該流程的 CI 系統的完整性。它同時也坦承了一個對任何想要重建這起事件的人而言都至關重要的缺口——在其進行分析時,攻擊者究竟是用何種確切手法接管帳號,仍是未知。

npm install 時會執行什麼:preinstall、Bun 1.3.13,以及一個 300 種模式的收集器

Elastic Security Labs 將此觸發機制描述為preinstall 鉤子(位於 package.json 中),該鉤子濫用 npm 的一項合法功能:在套件完成安裝前執行任意命令,且受害者無需進一步互動。該鉤子會啟動setup.mjs,它會檢查是否已存在 Bun JavaScript 執行環境。若不存在,投放器會偵測機器的平台與架構,下載Bun v1.3.13,從官方發布頁面下載、解壓縮、用它執行酬載,然後刪除暫存目錄以掩蓋痕跡。Wiz 獨立識別出使用者代理Bun/1.3.13正在發出惡意呼叫。此投放器為跨平台,鎖定 Linux、macOS 與 Windows。

此酬載經過高度混淆,各來源對其大小的說法略有出入:Elastic 指出其大小為711 千位元組,而 Orca Security 則指為728 KB。它採用控制流平坦化與 Base91 字串編碼手法,並帶有《沙丘》主題的字串——laza、kanly、ghola、mentat、lasgun、sietch、fedaykin、tleilaxu、sandworm、sardaukar、ornithopter、navigator——Elastic 指出這與先前的 Shai-Hulud 行動有相似之處。

微軟的行為分析補充了兩個值得注意的細節。該載荷會先檢查自身所處的環境,在俄語系統上退出,避免重複的實例,並在開發人員工作站上啟動一個分離的背景副本;在 CI 中,它則保持附加於作用中的作業,以便取得工作流程機密、執行器憑證與 OpenID Connect 發佈權限。

這個收集器正是讓此事件成為 AI 工具鏈相關事件、而非一般憑證事件的關鍵。Elastic 表示,它會掃描超過 300 種獨特模式,涵蓋開發者機器上的各憑證存放區,且值得注意的是,其目標鎖定AI 工具鏈憑證:Anthropic、Claude、Codex、Cursor、OpenAI 和 Gemini。它也會取得 AWS、GCP、Azure 和 Alibaba Cloud 憑證、GitHub 個人存取權杖、JWT 和工作階段權杖、HashiCorp Vault 權杖、SSH 私密金鑰、Kubernetes 服務帳戶權杖及 npm 權杖。Wiz 報告指出,相較於它據以建構的較早期 Mini Shai-Hulud 程式碼,目標清單已擴增近 70%,新增項目包括 Claude、OpenAI、Codex、Cursor 和 Gemini 的 AI 代理程式憑證存放區,Foundry、Solana 和 Monero 的加密貨幣金鑰庫,Jenkins 的 master.key、Argo CD 和 Harbor 機密,Alibaba 和 Tencent 的 CLI 設定,以及/etc/shadow。

Microsoft 與 Elastic 都描述了相同的資料外洩設計。結果會序列化為 JSON、以 gzip 壓縮,並使用隨機產生的 AES-256-GCM 金鑰加密,而該金鑰會以攻擊者的 RSA 公開金鑰包裝。酬載並未硬編碼其命令與控制網域:Elastic 表示它會查詢位於 0xE1f2395ee43e45A1556EC6438a88c31B83493103 的 Ethereum 智慧合約,以在執行階段取得目前端點,因此基礎設施可以在不更動惡意軟體的情況下輪替。若此方式失敗,它會尋找一個經密碼學簽章的標記——thebeautifulmarchoftime——,此標記位於 GitHub 提交歷史中,並會以內嵌的 RSA 金鑰驗證該網域。若兩者都失敗,它會透過受害者自己帳號所建立的公開 GitHub 儲存庫外洩資料,其描述為 "Shai-Hulud: Here We Go Again"。Microsoft 指出其中一條備援路徑會將竊取到的 GitHub 權杖以雙重 Base64 編碼,而非對其加密。

傳播以權杖品質為前提。Elastic 表示,蠕蟲只有在憑證掃描找到具備 套件寫入權限以及能夠在無需雙因素驗證的情況下發布的 npm 權杖時才會啟動;接著它會下載每個可寫入套件的最新 tarball,將自身注入,提升修補版號並重新發布。BleepingComputer 補充,每個權杖在被竊取前都會即時透過註冊表的 whoami 端點驗證。這套流程讓一個遭入侵的身分變成數百個發布版本,也是為什麼惡意版本看起來像一般的修補版號提升。

An HTML card titled 'The first four hours, 4 August 2026', subtitled 'What the sources put where in the infection order, and the three counts the campaign is quoted with'. A four-step numbered column headed 'Infection order' reads: 1, 09:00 UTC: files pushed to main — attacker adds IDE persistence payloads to the keyv repository, then publishes a new keyv version, per Wiz Research; 2, the victim's CI builds the payload — keyv 6.0.0 reaches npm through the compromised account's own GitHub Actions workflow carrying valid provenance and a SLSA Build Level 3 attestation, per Orca Security and Zscaler ThreatLabz; 3, the worm republishes with stolen tokens — stolen npm tokens with write access and 2FA bypass bump patch versions, at peak roughly one infected package per second, per Elastic Security Labs and Zscaler ThreatLabz; 4, IDE hooks travel with the repos — a stolen GitHub App token commits .claude/settings.json and .vscode/tasks.json to up to 50 branches per accessible repository, per Elastic Security Labs. A right-hand panel headed 'Three counts, three units' shows: 400+, unique npm packages compromised by 6 August, per Elastic and Microsoft Threat Intelligence; 868, worm-reached packages across 1,381 versions, per Aikido via BleepingComputer and Orca Security; 1,300+, package versions with 2 billion monthly downloads, per CSA Singapore advisory AD-2026-009, 6 August. A footer reads: each figure is a snapshot taken while the campaign was still running; none of the cited sources claims a final total.

無需 npm install 的感染途徑

讓本次攻擊活動與早期 npm 蠕蟲有所區別的是這項發現:安裝不再是唯一的入侵方式。Elastic 描述了另外兩條針對 AI 程式設計工具使用者的執行路徑。一個 SessionStart 掛鉤位於 .claude/settings.json 中,會執行 node .claude/setup.mjs;只要新的 Claude 工作階段開始就會觸發。至於 VS Code,一個 folderOpen 任務位於 .vscode/tasks.json 中,會執行 node .vscode/setup.mjs;只要受感染的儲存庫一開啟就會觸發。Microsoft 的分析列出相同的四個產物——.claude/settings.json、.claude/setup.mjs、.vscode/tasks.json 與 .vscode/setup.mjs——並將它們描述為次要感染途徑,可在原始 npm 安裝完成後重新啟動酬載。

使這種情況急遽擴大的條件,就藏在遭竊的憑證裡。當GitHub App 權杖也在其中時,Elastic 表示該蠕蟲會將惡意鉤子提交到每個可存取儲存庫最多 50 個分支,並將 .claude/settings.json 與 .vscode/tasks.json 注入每個分支。Elastic 的結論是,開發者若複製其中一個分支並開啟它,就可能因開啟該專案而遭到感染——整條路徑完全沒有套件安裝,因此也沒有安裝指令碼防禦。

Zscaler 的評估是,這些持久化鉤子在套件移除後仍會留存,而且只要在 VS Code 或 Claude Code 中開啟專案就會重新執行,因而繞過了--ignore-scripts這項緩解措施——許多團隊在先前 npm 蠕蟲事件後採用了此措施。其建議很直接:將 IDE 與 AI 代理程式設定檔——.claude/、.cursor/、.vscode/、.gemini/——視為可執行程式碼,並以與原始碼相同的嚴謹程度進行審查。

攻擊中與儲存庫有關的那一半有一個指紋。Elastic 報告指出,蠕蟲產生的提交可透過作者名稱 claude以及提交訊息chore: update config辨識出來,而 Wiz 也記錄到相同的訊息字串。Elastic 補充說,該提交訊息還夾帶了遭竊的 GitHub 權杖,以及一段恐嚇字串——IfYouBlockThisAPIKeyItWillCrashTheLiveProductionServersOfAllThirdPartyClients——Elastic 將其解讀為試圖嚇阻開發者撤銷該權杖。Wiz 在初始提交中也記錄到相同的字串,而在引入 IDE 掛鉤的提交中則換成了較短的訊息。

A generated abstract illustration on a deep navy field: a tall repository-shaped block stands at centre, its face divided into thin horizontal branch lines. A narrow beam of pale light from an editor-shaped pane at upper left falls across the block, and where the beam touches one branch line, a small bright hook symbol appears and a thin amber thread runs down into a dark pool at the base. The other branch lines remain untouched and faintly lit. No text, numbers, people, brand marks or organisation logos appear. The OrcaRouter logo is composited in the bottom-right corner.

計數並不一致,而這並不構成矛盾

針對影響範圍的每一個已公布數字,都各自對應到不同的單位,而這些單位無法互換。Elastic Security Labs 於 8 月 6 日撰文時計算出,超過 400 個不重複的 npm 套件遭到入侵。Microsoft Threat Intelligence 則描述超過 400 個套件,橫跨多個彼此無關的發佈者。根據 BleepingComputer 的引述,Aikido 表示這個數字是至少 868 個套件、涵蓋 1,381 個版本。Orca Security 報告指出,有 10 個直接遭投毒的 keyv 與 cacheable 套件,每月下載量超過 6.19 億次,接著另有 868 個套件與 1,381 個版本遭該蠕蟲觸及,每月安裝量超過 20 億次。新加坡 CSA 諮詢 AD-2026-009(日期為 8 月 6 日)記錄到超過 1,300 個遭入侵的套件版本,合計代表每月 20 億次下載。

那些是三個不同的分母——套件、套件版本與每月下載量——取自一場仍在進行中的活動的三個不同時刻。Zscaler 對速度的描述解釋了它們為何會出現分歧:該公司表示,這隻蠕蟲在不到四小時內自我傳播至超過 400 個套件,且在高峰時大約每秒發布一個受感染的套件。把較晚的計數視為對較早計數的修正會是錯誤的;每個都只是快照,且所引用的來源中沒有任何一個聲稱最終總數。

Elastic 在函式庫層級所公布的暴露數據,是最常被引用、也最不含糊的一組。該公司回報,光是 keyv 在上個月就超過 6 億次下載,flat-cache 接近 5.8 億次,cacheable-request 超過 1.37 億次,cacheable 超過 3,000 萬次,cache-manager 則超過 1,600 萬次。CSA 的公告列出了具體受影響的版本,其中包括 keyv 6.0.0、flat-cache 6.1.24、file-entry-cache 11.1.6、cacheable-request 13.0.20、cacheable 2.5.1、cache-manager 7.2.10、@cacheable/utils 2.5.1 以及 ecto 5.0.1。

撤銷陷阱

安裝了受影響版本的應變人員,在第一個問題之後還會面臨第二個問題。Elastic 指出,在有條件的 GitHub 備援路徑中,該酬載會試圖安裝一個權杖監控元件,該元件可維持對憑證的存取權,且包含一個在受監控權杖遭撤銷時觸發的破壞性處理程序。Zscaler 以營運細節描述了這項機制,並將其命名為「權杖撤銷陷阱」:該蠕蟲會安裝一個背景程序,每 60 秒使用竊得的權杖輪詢 GitHub API,若該權杖傳回 4xx 錯誤——也就是受害者已將其撤銷——便會觸發次要的破壞性酬載,而視變體而定,這可能包括遠端程式碼執行或刪除使用者的主目錄。

Wiz 補充說,死人開關會根據命令與控制伺服器的回應選擇性啟用:操作者可以回傳一個值,指定要啟用哪個命令,以及該開關應監視哪個權杖以偵測撤銷。Wiz 也指出,監視器會尋找來自使用者端點的有效回應,因此任何在該處有效的權杖類型都可作為觸發條件。

其實際後果已由 BleepingComputer 及其所引用的 Aikido 指引記錄在案:曾安裝受影響版本的開發人員工作站或 CI/CD 執行器,都應被視為已遭入侵即使該套件隨後已被移除,因為第二階段的執行可能已導致權杖外洩,並破壞了建置的完整性。Microsoft 的指引從建置端得出相同結論,警告那些在啟用生命週期指令碼的情況下安裝了受影響套件的組織,應將該工作站或建置執行器視為可能已遭入侵,並從受信任的來源重建受影響的系統及下游產物。

An HTML card titled 'Established, assessed, and not shown', subtitled 'The same five analyses, sorted by how strongly each claim is supported — not by how confidently it is written'. Three columns. ESTABLISHED lists: the keyv maintainer's GitHub account was compromised, files were pushed to main and a release was published on 4 August 2026; at least keyv 6.0.0 shipped through the victim's own CI with valid provenance and SLSA Build Level 3; a preinstall hook ran setup.mjs, which downloaded Bun v1.3.13 to execute an obfuscated payload; the collector scanned 300+ credential patterns including Anthropic, Claude, Codex, Cursor, OpenAI and Gemini; hooks in .claude/settings.json and .vscode/tasks.json run on session start and folder open; a GitHub App token extended the hooks to up to 50 branches per accessible repository; more than 400 unique packages were compromised within days; CSA Singapore published advisory AD-2026-009 on 6 August 2026. ASSESSED lists: attribution to the Mini Shai-Hulud family and a TeamPCP lineage; that the account takeover was the initial access route; that provenance must not be read as proof of safety, since it validates the pipeline and not the account; that IDE configuration files should be treated as executable code. NOT SHOWN lists: how the maintainer account was taken over, reported as unknown by Zscaler; any single final total, since the counts use packages, versions and downloads interchangeably; any confirmed reuse of a stolen AI-tooling credential against a provider account; who the operator is beyond vendor attribution; any remediation outcome, account recovery or enforcement action. A footer cites Elastic Security Labs, Microsoft Threat Intelligence, Wiz Research, Orca Security and CSA Singapore AD-2026-009.

哪些是已確立的、哪些是已評估的,以及哪些是還沒有人展示過的

主要紀錄與五份獨立分析在運作機制上趨於一致,而關於機制的論述是該檔案中最有力的部分。

• keyv 維護者的 GitHub 帳號遭入侵,惡意檔案在版本發布前被直接推送到 main,時間為 2026 年 8 月 4 日——Wiz、Orca Security、BleepingComputer 與 CSA Singapore 均一致報導。

• 至少 keyv 6.0.0 是透過受害者自己的 CI 管線進入 npm,並帶有有效的來源證明,而 Zscaler 指明其具備 SLSA Build Level 3 證明。這正是讓此事件值得注意的說法,且獲得三個彼此未共同撰寫對方工作的組織佐證。

• 一個預安裝掛鉤執行了 setup.mjs,該檔案下載了 Bun v1.3.13,並執行一段經混淆的酬載,掃描了超過 300 種憑證模式,其中包括 AI 程式設計工具的憑證——Elastic 與 Wiz 對於執行階段版本及這份以 AI 為目標的憑證清單的看法一致。

• 寫入 .claude/settings.json 和 .vscode/tasks.json 的 Hook 會在 session 開始時及資料夾開啟時執行,而 GitHub App token 則將此擴展到每個可存取的儲存庫最多 50 個分支——這是 Elastic 的發現,也是其聲稱開發者可能因開啟儲存庫而遭感染的依據。

• 超過 400 個不同的套件在數天內遭到入侵,而國家監管機構新加坡網路安全局(CSA Singapore)於 2026 年 8 月 6 日發布公告 AD-2026-009,列出受影響的版本與指標。

來源視為評估而非事實的部分應予以標示。Wiz 將該酬載描述為「Mini」Shai-Hulud 惡意軟體家族的子代,建構於 TeamPCP 所發布的公開 Shai-Hulud-Open-Source 儲存庫之上,並做了幾項關鍵變更;Orca Security 將該攻擊歸因於 TeamPCP;Zscaler 將 ChainDrop 與 TeamPCP 連結,並將其置於一條自 2025 年 9 月起的譜系之中。那是各家廠商在歸因上的共識,而非所引用的第一手文件對某個具名個人或團體所能證明的事。

有三件事沒有任何引用來源能夠確立,而本文也未加以補足。第一,如何維護者帳號遭到接管:Zscaler 明確表示,在其分析時,確切機制仍不明。第二,單一最終總數:400、868 和 1,300 這些數字在不同時刻分別計入套件、套件與版本,以及版本,且沒有任何來源聲稱該行動已結束。第三,也是對本紀錄中針對 AI 的特定說法最重要的一點,沒有任何引用來源報導已確認的案例:遭竊的 Anthropic、Codex、Cursor、Gemini 或 OpenAI 憑證被重放至供應商帳戶。有紀錄的是意圖與能力——一份明確的目標清單,以及一個為觸及該清單而打造的收集器——而不是已證實發生對 AI 供應商系統的下游入侵。

之後有什麼改變——以及應變人員必須做什麼

紀錄中最具體的補救措施是進行平台變更。Elastic 建議升級至 npm 12 或更新版本,其預設會封鎖 preinstall 掛鉤;微軟的指引也獨立建議採用 npm CLI v12 與 min-release-age功能,兩者都會將新版本延後足夠長的時間,讓社群能在版本進入建置流程前先發現遭入侵的情況。

除此之外,各來源所公布的應對步驟高度重疊。

• Elastic:撤銷受影響機器上所有 GitHub 權杖(包括工作階段權杖);撤銷並重新產生 npm 權杖,尤其是具有寫入權限與可繞過雙因素驗證的自動化權杖;搜尋儲存庫中是否有未經授權、訊息為 chore: update config from claude@users.noreply.github.com 的提交;輪替雲端、Kubernetes、Vault、AI 工具鏈與 CI/CD 密鑰;在 npm 帳號上啟用雙因素驗證。

• Microsoft:在受影響的端點與建置主機上清除 npm 與 yarn 快取,釘選已知良好的版本,檢查鎖定檔與產物中是否含有遭入侵的版本(包括遞移參照),重建共用基礎映像與黃金建置執行器,並檢視權杖範圍、工作流程核准與發布來源證明,因為此事件與透過 OIDC 發布濫用 CI/CD 管線的情況相符。

• CSA Singapore:從開發、建置及 CI/CD 環境中移除受影響的版本,將受影響系統視為已遭入侵並予以重建,輪替憑證,檢視雲端與原始碼環境是否有未經授權的存取,監控已公布的入侵指標,並強化允許清單、完整性驗證及來源追溯控管。

• Zscaler:將 .claude/、.cursor/、.vscode/ 與 .gemini/ 視為可執行程式碼,並停止把 SLSA 或 Sigstore 的來源證明當成安全的保證——改為疊加針對發布行為的異常偵測,例如非上班時段發布、批量發布多個版本,以及首次發布者。

該紀錄未包含補救結果。沒有任何引用來源報導惡意版本已被完全移除、帳號復原、逮捕或監管執法行動;CSA 的公告是對防禦者的通知,並非對某一方作出的認定。

這起事件改變的是一種分類。開發者工具的設定檔是一條執行路徑,而編輯器開啟資料夾則是一個執行事件。來源證明是在陳述某個套件是由哪條管線產生的——而不是在陳述該管線執行時是誰持有金鑰;而這正是第一個 keyv 發行版所掉入的缺口。