觀點 · 資訊分享

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 題常見問題
標籤
#npm#供應鏈攻擊#TanStack#CVE-2026-45321#GitHub Actions
TanStack 的 42 個 npm 套件被發布 84 個惡意版本:5 月 11 日裝過就要當作中招

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

TanStack 套件遭下毒資訊圖卡:5/11 裝過 TanStack 套件的電腦,要當作已被入侵

先用白話講:供應鏈攻擊是什麼?

想像你每天去同一家早餐店買東西,店家的食材都是向固定的批發商進貨。如果批發商的貨被人偷偷調包,你什麼都沒做錯,還是會吃到有問題的東西。

供應鏈攻擊就是這個道理:開發者寫程式會裝很多別人寫好的套件,如果套件被換成有毒的版本,裝的人就中招。這次被動手腳的,是前端圈很常用的 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 之後有沒有可疑動作。
LINE