開發者注意:keyv / cacheable 供應鏈 worm「Shai-Hulud: Here We Go Again」
前幾日喺 GitHub 同 X 上面見到好多人講一單 npm supply chain攻擊,最初我以為又係普通 typosquatting,點知越睇越覺得唔對路,今次唔係邊緣 package,係直插 JavaScript 生態系最底層嘅 keyv 同佢嘅 cacheable 家族。呢幾日我睇咗幾份報告,包括 Lidor Machluf / Upwind Security 喺 cacheable repo 嘅詳細分析、OpenSSF Malicious Packages 嘅Filing同埋 Socket / Aikido / SafeDep 嘅公開報道,呢度同大家整理吓我見到嘅
什麼是 Keyv?為何它的淪陷是一場生態系災難?
keyv 本身係一個喺 Node.js 生態系極受歡迎嘅輕量級Key-Value 儲存介面,佢提供統一 API,俾開發者可以無縫喺 Redis、MongoDB、PostgreSQL 或本機記憶體之間切換快取策略。但 keyv 絕唔係普通 npm 套件,佢同 flat-cache、file-entry-cache、cacheable、cacheable-request、cache-manager 等一齊,構成咗 JavaScript 開發工具鏈嘅 "底層基礎設施"。
呢啲套件每週下載量合計超過 5 億次(單係 keyv 同 flat-cache 已經過億),而且係 ESLint 呢啲核心工具嘅隱性依賴。佢哋處於無數企業專案 dependency tree 嘅極深處。當攻擊者奪取 maintainer 帳號並落毒,唔係單一專案受害,而係成個生態系嘅 "水源頭" 被落毒。
今次攻擊係幾時發生,對象係乜嘢
事件係 2026-08-04 UTC 早上 爆發。攻擊者入侵咗 jaredwray 嘅 GitHub 帳號(即 keyv 同 cacheable 嘅 maintainer),透過 GitHub Actions OIDC 發布咗以下 10 個受污染版本,全部加咗 "preinstall": "node setup.mjs":
| 套件 | 有毒版本 | 上一個乾淨版本 | 每週下載 |
|---|---|---|---|
keyv |
6.0.0 |
5.6.0 / 6.0.0-rc.1 |
~154M |
flat-cache |
6.1.24 |
6.1.23 |
~150M |
file-entry-cache |
11.1.6 |
11.1.5 |
~148M |
cacheable |
2.5.1 |
2.5.0 |
~8M |
cacheable-request |
13.0.20 |
13.0.19 |
~34M |
cache-manager |
7.2.10 |
7.2.9 |
~4M |
@cacheable/net |
2.1.1 |
2.1.0 |
少 |
@cacheable/node-cache |
3.1.2 |
3.1.1 |
~2M |
@cacheable/memory |
2.2.1 |
2.2.0 |
~7M |
@cacheable/utils |
2.5.1 |
2.5.0 |
~9M |
之後攻擊利用偷到嘅 npm / GitHub token 繼續自我複製,總共波及 444 個 packages / 2,234 個 versions(OpenSSF 數字),橫跨多個 npm namespace。
發生咩事,嚴重性係點樣
執行流程簡化嚟講係咁:
npm install觸發preinstall→ 跑setup.mjssetup.mjs下載 / 執行Math_Symbol.js(一個用 Bun 編譯嘅 CJS payload)- Payload 會偷 npm token、GitHub token、AWS / GCP / Azure / Stripe key、DB connection string、私鑰、CI secrets 等等
- 用偷到嘅 token 再發布更多惡意版本,形成 worm
最得人驚嘅幾點:
- 無固定 C2:exfiltration 經 GitHub dead-drop repositories 同 DNS 進行,傳統 URL reputation 防禦察覺唔到。
- Dead-man's switch:payload 會裝一個
gh-token-monitor程序,每隔 60 秒用偷到嘅 token 打api.github.com/user。一旦你 revoke 咗個 token,佢偵測到 40x 就會觸發額外 handler。所以直接 rotate token 反而可能引爆下一步。 - CI memory scraping:針對 GitHub Actions
Runner.Worker程序讀/proc/<pid>/mem,log masking 擋唔到。 - 開 repo 都中:repo 本身被種咗
.claude/settings.json同.vscode/tasks.json,喺 VS Code 開 folder 或 AI agent 啟動 session 都會觸發執行——唔使 npm install。
呢次唔係「改個 function 偷啲 data」咁簡單,係針對整條 CI/CD 同開發者工作流嘅持續性攻擊。
中小企需唔需要理會
老實講,只要有用 Node.js / npm,就一定要理會。 原因好簡單:
- 你未必直接裝
keyv,但 ESLint、Prettier 周邊工具、Next.js / Nuxt / Vite 生態、各種 CLI 都會間接引進flat-cache/file-entry-cache。 - 只要任何一個開發者或 CI 喺 8 月 4 日之後
npm install過,就有可能被執行咗 preinstall hook。 - 中小企通常冇專職 security team,一個中招可能就洩露咗整個 GitHub / npm / AWS 憑證,後果可以好大。
如果你完全冇用 Node.js,影響就相對間接,但係開發團隊若有使用相關工具,都要提醒佢哋檢查。
有冇簡易方法檢查自己系統有冇受影響
以下係我會做嘅幾步,最快 5 分鐘可以知道大約情況:
1. 檢查 package.json / lockfile 有冇中標版本
# npm
npm ls keyv flat-cache file-entry-cache cacheable cacheable-request cache-manager @cacheable/net @cacheable/node-cache @cacheable/memory @cacheable/utils
# 直接 grep lockfile
grep -E "keyv@6\.0\.0|flat-cache@6\.1\.24|file-entry-cache@11\.1\.6|cacheable@2\.5\.1|cacheable-request@13\.0\.20|cache-manager@7\.2\.10" package-lock.json yarn.lock pnpm-lock.yaml 2>/dev/null
2. 檢查 persistence 同惡意檔案
# dead-man's switch 可能留下的檔案
ls -la ~/.config/gh-token-monitor/ ~/.local/bin/gh-token-monitor.sh ~/Library/LaunchAgents/com.user.gh-token-monitor.plist ~/.config/systemd/user/gh-token-monitor.service 2>/dev/null
# 可疑 process
ps aux | grep -E "gh-token-monitor|bun_environment|Math_Symbol|setup_bun" | grep -v grep
# 被植入的 IDE / agent 設定
find ~ -maxdepth 6 \( -path "*/.claude/settings.json" -o -path "*/.vscode/tasks.json" \) -newer "2026-08-01" 2>/dev/null | xargs grep -l "setup.mjs\|math_init" 2>/dev/null
3. 用 npm audit / SCA 工具
npm audit
或者用 Snyk、Socket、GitHub Dependabot alerts 掃描。OpenSSF Malicious Packages 已經收錄咗呢次事件,支援 OSV 嘅工具會報出嚟。
4. 檢查 GitHub repos 有冇被加入可疑 workflow
# 用 gh CLI 列出自己嘅 repos,搵 "Shai-Hulud: Here We Go Again" 描述
gh repo list --json name,description | grep -i "hulud"
# 搵可疑 workflow
find . -path "*/.github/workflows/*" -name "*.yml" -o -name "*.yaml" | xargs grep -l "toJSON(secrets)\|Run Copilot" 2>/dev/null
可唔可以利用 AI Agent 幫手檢測甚至修復受影響系統
呢個問題我覺得最有趣,因為本身呢次攻擊都有針對 AI agent 嘅 hook(.claude/settings.json 嘅 SessionStart)。所以結論係:可以,但一定要識用。
AI Agent 適合做嘅嘢
- 大規模掃描 lockfile:比人眼快好多,可以一次過檢查幾十個 repo 有冇中標版本。
- 產生 remediation PR:自動 pin 返去乾淨版本、開 PR、更新
package.json同 lockfile。 - 協助寫 incident response runbook:整理檢查清單、輪轉憑證步驟。
- 分析 CI logs / artifacts:搵
format-results.txt等可疑檔名。
使用 AI Agent 嘅風險
- 唔好直接叫 agent 打開受影響 repo 做分析:如果
.claude/settings.json或.vscode/tasks.json被植入,agent session 一啟動就可能觸發 payload。 - 先隔離後掃描:用 Docker、乾淨 VM 或者
--ignore-scripts環境,先確認 repo 冇毒先俾 agent 處理。 - agent 睇唔到所有東西:例如 dead-man's switch 喺系統層面,agent 可能冇權限或冇 context 發現。
我會用嘅 workflow
1. 人類先用上文的 5 分鐘檢查做第一輪篩選。
2. 若懷疑 repo 乾淨,才用 AI agent 掃描 lockfile 並產生 pin-version PR。
3. 若發現任何 persistence 檔案,人類處理(或懂安全的 agent 在隔離環境處理)。
4. 修復後再 rotate 所有相關 token——次序好重要,先清 malware 再 rotate。
以下係一個可以餵畀 AI agent 嘅 prompt 範例:
Scan all
package-lock.json,yarn.lock, andpnpm-lock.yamlfiles under/path/to/projects. Report any occurrence of these compromised versions: keyv@6.0.0, flat-cache@6.1.24, file-entry-cache@11.1.6, cacheable@2.5.1, cacheable-request@13.0.20, cache-manager@7.2.10, @cacheable/net@2.1.1, @cacheable/node-cache@3.1.2, @cacheable/memory@2.2.1, @cacheable/utils@2.5.1. Do not run any install scripts. If found, generate a summary table with package, version, project path, and parent dependency chain.
我會點做總結
呢次事件再次證明咗供應鏈安全唔係大廠專利,中小企一樣要面對。最實際嘅幾件事:
- 立即檢查 lockfile,睇下有冇中標版本。
- 用
--ignore-scripts做新 install,阻止 preinstall hook 執行。 - 先清 malware / persistence 再 rotate token,唔好顛倒次序。
- 長遠啲:pin exact versions、用
min-release-age(例如 npm 嘅npm config set min-release-age=7)、啟用 Dependabot / Snyk / Socket、分拆 CI secrets。
最後一句:開源生態嘅信任鏈真係好脆弱,我哋每個用 npm 嘅人都係鏈上嘅一環。保持警覺,但唔好驚到唔敢寫 code——做足基本檢查,大部分風險都可以控得住。😄
參考來源:
- jaredwray/cacheable #1692 – Lidor Machluf / Upwind Security 完整 payload 分析
- OpenSSF Malicious Packages PR #1423 – keyv/cacheable core
- OpenSSF Malicious Packages PR #1426 – 全波 444 packages / 2,234 versions
- Socket Threat Research: Popular npm packages in the keyv and cacheable namespaces compromised
- Aikido Security: keyv and friends compromised in npm supply chain attack
- SafeDep: keyv npm supply chain compromise
- DataDog IOCs: Shai-Hulud 2.0