觀點 · 資訊分享
TanStack 的 42 個 npm 套件被發布 84 個惡意版本:5 月 11 日裝過就要當作中招
5 月 11 日短短幾分鐘內,TanStack 的 42 個套件被塞進 84 個惡意版本,安裝時就會偷走雲端、GitHub 與 SSH 的登入資料,還會試圖感染受害者自己維護的套件。CVE-2026-45321,CVSS 9.6。
- 發布
- 2026-05-12
- 篇幅
- 約 4 分鐘 · 1,721 字
- 結構
- 8 節 + 3 題常見問題
- 標籤

一句話看懂:5 月 11 日,TanStack 的 42 個 npm 套件被發布了 84 個惡意版本,安裝時會偷走開發機與 CI 上的登入資料,當天裝過的環境要當作已被入侵。

先用白話講:供應鏈攻擊是什麼?
想像你每天去同一家早餐店買東西,店家的食材都是向固定的批發商進貨。如果批發商的貨被人偷偷調包,你什麼都沒做錯,還是會吃到有問題的東西。
供應鏈攻擊就是這個道理:開發者寫程式會裝很多別人寫好的套件,如果套件被換成有毒的版本,裝的人就中招。這次被動手腳的,是前端圈很常用的 TanStack(Router、Start 等)系列。
發生什麼事
根據 GitHub 的安全公告(CVE-2026-45321,CVSS 9.6,嚴重等級 Critical):
- 5 月 11 日 UTC 時間約 19:20 到 19:26,42 個 @tanstack/* 套件被發布了 84 個惡意版本,每個套件各兩個
- 發布是透過 TanStack 專案本來就綁定的 GitHub Actions 發布身分完成,發布流程本身沒被改過,所以看起來像正牌官方版本
- 攻擊者串連了三種已知的弱點:
pull_request_target設定不當、跨分支的快取污染,以及在執行環境中從記憶體取出發布用的身分憑證
惡意程式做了什麼
安裝時會執行一支約 2.3 MB、被混淆過的腳本,它會:
- 蒐集 AWS 與 GCP 的中繼資料服務內容、Kubernetes 服務帳號、HashiCorp Vault、
~/.npmrc、GitHub token 與~/.ssh/裡的 SSH 私鑰 - 把蒐集到的資料經由 Session 即時通訊網路上傳,因為加密且沒有固定的控制伺服器,官方說網路層面只能用封鎖 IP 或網域來防
- 查出受害者自己維護的 npm 套件,用同樣方式重新發布,讓感染繼續擴散
我該怎麼辦
| 情況 | 建議做法 |
|---|---|
| 5/11 約 19:20 後曾安裝過 @tanstack/* | 當作已被入侵,立刻更換該環境可存取的所有登入資料 |
| CI 在該時段跑過安裝 | 把 runner 當作已洩漏,並檢查雲端稽核紀錄 |
| 還沒更新 | 鎖定在 5/11 19:00 UTC 以前發布的版本,或升級到公告列出的修正版 |
給開發者的技術細節
- 惡意版本的 package.json 會多一個
optionalDependencies,指向名為@tanstack/setup的項目;這不是 npm 上的真套件,而是指向 GitHub 分支網路裡的一個孤立 commit - 套件根目錄會多出一個
router_init.js,且沒有列在files欄位 - 不要用
npm install來檢查,改用npm pack下載 tarball 解開看,這樣不會執行生命週期腳本 - 暫時性防護:
npm config set ignore-scripts true,並刪掉 node_modules 與 lockfile 後重新安裝 - 修正版舉例:@tanstack/react-router 修正在 1.169.9、@tanstack/vue-router 也是 1.169.9,其他套件請對照公告的表格
我的看法
我自己的專案多半用 Nuxt、Vue,乍看跟 TanStack 沒關係,但 @tanstack/vue-router 也在受影響名單裡,不能掉以輕心。對接案者來說,最麻煩的是「客戶的 CI 也可能跑過」:交付專案時最好把 lockfile 鎖死,並把安裝腳本的權限收緊。
另外這件事提醒我,好用的套件一定要搭配「最小權限」:CI 裡不要放不必要的金鑰,因為只要安裝流程被劫持,所有放在環境裡的東西都會一起被帶走。
名詞小辭典
- npm:JavaScript 世界最大的套件下載站,裝套件時就是從這裡下載。
- CI:持續整合,程式一上傳就自動測試、打包的流程,通常會放不少金鑰。
- OIDC:一種讓系統證明「我是誰」的機制,這次攻擊者拿到的就是發布用的身分證明。
- lockfile:記錄每個套件確切版本的檔案,能避免悄悄換成別的版本。
資料來源
常見問題
什麼是供應鏈攻擊?
不直接攻擊你,而是攻擊你信任的零件:你安裝的套件被換成有毒的版本,所以你照平常方式安裝,等於自己把惡意程式請進家裡。
我怎麼知道自己有沒有裝到?
官方建議檢查已鎖定版本的 package.json:惡意版本的 optionalDependencies 裡有一個名為 @tanstack/setup 的項目(npm 上並沒有這個真套件),而且套件根目錄會多出一個約 2.3 MB 的 router_init.js。可以用 npm pack 下載來看而不會執行安裝腳本。
有中招該做什麼?
把當時可被安裝流程存取到的所有登入資料都換掉(雲端金鑰、GitHub token、npm token、SSH 金鑰等),並檢查雲端稽核紀錄在 5/11 之後有沒有可疑動作。
接著讀
全部觀點 →資安公司 CrowdSec 程式碼外流:起因是 5 月 TanStack 套件被下毒,離職員工帳號沒及時移除CrowdSec 公開事件報告:約 170 個私有 GitHub 程式庫在 5 月被下載、9 月 16 日被貼上論壇。源頭是一位剛離職、仍留在 GitHub 組織裡的工程師電腦,被 TanStack npm 供應鏈攻擊偷走了權杖。閱讀 →Axios 的兩個 npm 新版被植入惡意程式:裝到 1.14.1 或 0.30.4 的人,請換掉機器上的所有金鑰每週下載量超過 7,000 萬的 HTTP 套件 Axios,在 3/31 被發布兩個惡意版本。微軟 4/1 發布分析並歸因給北韓駭客組織 Sapphire Sleet,建議降版並更換所有可能外洩的憑證。閱讀 →LiteLLM 發布管線被入侵:v1.107.0 帶著偷憑證程式上了 PyPI 與 Docker,約 2 小時後下架常用的 AI 閘道套件 LiteLLM 在 10 月 21 日被攻擊者透過發布流程推出惡意的 v1.107.0。這個版本會竊取憑證,在 PyPI 約 2 小時、Docker 約 2.5 小時後被撤下,沒鎖版本的人要檢查並換金鑰。閱讀 →