# Dependabot 的一次版本升級發布了蠕蟲。共 22 個套件。

Published: 2026-09-17

一個機器人開啟了一個 Pull Request。人類在 24 分鐘後將其合併。95 分鐘後，一條蠕蟲利用在其 CI 中找到的令牌，以他的名義發布了其 22 個 npm 套件的 110 個惡意版本。

Canonical: https://thedailydiff.dev/zh-TW/video/2026-09-17-dependabot-tanstack/

## 本影片重點

- 一個機器人、一個人、一條蠕蟲
- 事情如何發生、為何 npm 允許、誰該負責
- 時間線：被污染的快取
- 21:48 — Dependabot 的版本升級
- 為何會成功

## 章節

- 0:00 一個機器人、一個人、一條蠕蟲
- 0:20 事情如何發生、為何 npm 允許、誰該負責
- 0:30 時間線：被污染的快取
- 1:15 21:48 — Dependabot 的版本升級
- 1:50 為何會成功
- 2:20 git blame
- 2:45 影響範圍
- 3:00 結論

## 翻譯文字稿

譯自英文原版旁白。可用的音訊和字幕由 YouTube 控制。

### 一個機器人、一個人、一條蠕蟲

0:00 一個機器人開啟了一個 Pull Request；一個人於二十四分鐘後將其合併。 九十五分鐘後，一條蠕蟲已發布了 其一百一十個版本的 套件，假冒他的身分。 TanStack 的事後報告包含了上游的時間戳，下游維護者的 包含了其餘內容，而 Hacker News 給了它一千一百個點讚和一個名字：迷你 沙丘魔堡。事情如何發生、為何 npm 允許、誰該負責。

### 事情如何發生、為何 npm 允許、誰該負責

0:21 這是 The Daily Diff，事後報告。 5 月 11 日，早上。 一個重新命名的分支對 TanStack Router 開啟了一個 Pull Request。 它在一小時內關閉，但一個基準測試工作流已經執行了它的程式碼並

### 時間線：被污染的快取

0:33 在發布工作流將使用的金鑰下保存了一個被污染的快取。 晚上七點二十。一次合法的合併運行了發布。 快取返回，一個二進位文件讀取執行器的記憶體， 竊取了發布令牌，並在四十二個套件中發布了八十四個版本， 帶有有效的來源證明。 測試失敗。它仍然發布了。 晚上七點四十六分，StepSecurity 研究員提交了問題；到國際標準時間九點， 所有內容都被棄用，並且諮詢報告也已發布。

0:55 棄用並不代表消失：npm 拒絕撤銷任何有依賴項的套件， 因此它在數小時內仍然可以安裝。 晚上九點四十八分。在一個九星級的航空數據專案中， Dependabot 開啟了其例行性的 Pull Request：升級開發依賴項組， 十三個更新。其中兩個是被污染的 TanStack 版本。 晚上十點十二分：已合併。發布工作流程在作用域內使用令牌運行 npm C-I；

### 21:48 — Dependabot 的版本升級

1:15 一個準備腳本讀取了它，並在晚上十點十七分，蠕蟲以他的身份發布了 每個人可以接觸到的套件的五個版本， 甚至是一個舊的支線專案：一個經典令牌用於所有。 九十五分鐘內發布了一百一十個版本。 他在午夜過後透過電子郵件得知此事。 為何它會成功。 第一：npm install 預設運行陌生人的生命週期腳本， 並且一個 git 依賴項的 prepare 腳本也算數。

1:39 第二：蠕蟲想要一件事：一個無需第二因素即可發布的令牌。 然後它會詢問註冊表該維護者還擁有什麼， 並將所有內容連同自己一起重新發布。 第三：鏈條中沒有任何環節是人。

### 為何會成功

1:51 一個機器人提議，一個管道安裝，然後蠕蟲投桃報李：它的 死信分支被命名為 dependabot/github-actions/fremen。 git blame。npm 的安裝模型，百分之五十五：腳本在安裝時運行， 棄用的仍可安裝，存在雙因素繞過令牌。 TanStack 的 CI，百分之二十五：一個未經審計的 Pull Request 目標工作流運行 具有快取寫入權限的 fork 程式碼。 升級習慣，百分之十五：在二十四分鐘內合併了十三個更新， 令牌在房間裡。

2:17 Dependabot，百分之五：如此信任，以至於蠕蟲穿上了它的制服。

### git blame

2:20 影響範圍：四十二個 TanStack 套件。 下游二十二個，來自一個只有九顆星的專案。 一旦蠕蟲到達 Mistral，整個生態系統超過一百六十個。 每個上游版本都帶有有效簽名：由官方 管道構建。確實如此。結論，事後報告：SHIP IT。 兩位維護者都在一天內發布了帶有時間戳的事後報告；三天內， 下游管道使用 ignore-scripts 進行安裝， 將建置與發布分離，並棄用了長期存在的令牌。

### 影響範圍

2:47 npm 的預設值沒有改變。 週一：安裝時 ignore-scripts，並且發布令牌從運行它的作業中移除。 在評論中，或在 thedailydiff.dev 寄給我您仍然不允許談論的事件。 在評論中，或在 thedailydiff.dev 寄給我您仍然不允許談論的事件。 這就是今天的差異。

### 結論

3:00 我是來自 Axrisi 的 Niko。 請負責任地合併。

## 來源

- [TanStack postmortem (Tanner Linsley, May 11, refined May 15)](https://tanstack.com/blog/npm-supply-chain-compromise-postmortem) — tanstack.com
- [TanStack "Hardening TanStack After the npm Compromise" (May 12)](https://tanstack.com/blog/incident-followup) — tanstack.com
- [TanStack/router#7383 — the StepSecurity detection issue](https://github.com/TanStack/router/issues/7383) — github.com
- [Downstream incident post, @squawk/\* (May 12)](https://github.com/neilcochran/squawk/discussions/251) — github.com
- [Downstream hardening post (May 14)](https://github.com/neilcochran/squawk/discussions/264) — github.com
- [The Dependabot PR #246 (opened 21:48 UTC, merged 22:12)](https://github.com/neilcochran/squawk/pull/246) — github.com
- [@tan\_stack advisory post, 21:19 UTC](https://x.com/tan_stack/status/2053948103766716630) — x.com
- [StepSecurity — worm internals, bypass\_2fa search, Dependabot-style branch names](https://www.stepsecurity.io/blog/mini-shai-hulud-is-back-a-self-spreading-supply-chain-attack-hits-the-npm-ecosystem) — www.stepsecurity.io
- [Socket](https://socket.dev/blog/tanstack-npm-packages-compromised-mini-shai-hulud-supply-chain-attack) — socket.dev
- [Aikido — "over 160 packages, including Mistral"](https://www.aikido.dev/blog/mini-shai-hulud-is-back-tanstack-compromised) — www.aikido.dev
- [Hacker News (1,097 points)](https://news.ycombinator.com/item?id=48100706) — news.ycombinator.com
