# Dependabot 提交的更新发布了一个蠕虫。涉及22个软件包。

Published: 2026-09-17

一个机器人打开一个拉取请求。一个人在24分钟后将其合并。95分钟后，一个蠕虫利用其CI中发现的令牌，以该人的名义发布了其22个npm软件包的110个恶意版本。

Canonical: https://thedailydiff.dev/zh-CN/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 一个机器人打开了一个拉取请求；一个人在二十四分钟后将其合并。 九十五分钟后，一个蠕虫已经发布了 其一百一十个版本的 软件包，以他的名义。 TanStack的事后分析有上游时间戳，下游维护者的 有其余的，Hacker News给了它一千一百分并起了一个名字：Mini Shai-Hulud。事情如何发生，npm为何允许，谁该受责备。

### 事情如何发生，npm为何允许，谁该受责备

0:21 这里是《The Daily Diff》事后分析。 5月11日，早上。 一个重命名的分支向TanStack Router打开了一个拉取请求。 它在一小时内关闭，但一个基准工作流已经运行了它的代码并

### 时间线：中毒的缓存

0:33 在发布工作流将使用的键下保存了一个中毒的缓存。 19:20。一次合法的合并运行了发布。 缓存返回，一个二进制文件读取了运行器的内存， 提取了发布令牌，并在四十二个软件包中发布了八十四个版本， 具有有效的来源。 测试失败。它仍然发布了。 19:46，一位StepSecurity研究员提交了问题；到UTC时间9点， 一切都已弃用，并且警告已发布。

0:55 弃用并非消失：npm拒绝取消发布任何有依赖项的东西， 所以它会保持可安装状态数小时。 21:48。在一个九星级的航空数据项目中， Dependabot打开了它的常规拉取请求：更新开发依赖组， 十三个更新。其中两个是中毒的TanStack版本。 22:12：合并。发布工作流运行带有范围内的令牌的npm C-I；

### 21:48 — Dependabot 的更新

1:15 一个准备脚本读取了它，并在22:17蠕虫以他的名义发布了。 令牌能触及的每个软件包有五个版本， 甚至是一个旧的副项目：一个经典的令牌用于所有。 九十五分钟内发布了一百一十个版本。 他在午夜后通过电子邮件得知此事。 为何会奏效。 一：npm install默认运行陌生人的生命周期脚本， git依赖项的prepare脚本也算在内。

1:39 二：蠕虫只想要一件事：一个无需二次验证即可发布的令牌。 然后它询问注册表该维护者还拥有什么， 并重新发布所有这些，将自身包含在内。 三：链条中没有任何一个是人。

### 为何会奏效

1:51 一个机器人提议，一个管道安装，而蠕虫则投桃报李：它的 死信分支被命名为dependabot/github-actions/fremen。 git blame。npm的安装模型，百分之五十五：脚本在安装时运行， 弃用的仍然可安装，存在绕过双因素的令牌。 TanStack的CI，百分之二十五：一个未经审计的拉取请求目标工作流运行 对缓存有写入权限的fork代码。 更新习惯，百分之十五：在二十四分钟内合并了十三个更新， 令牌在场。

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

### git blame

2:20 影响范围：四十二个TanStack软件包。 下游二十二个，来自一个九星级项目。 一旦蠕虫抵达Mistral，整个生态系统将超过一百六十个。 每个上游版本都带有有效的签名：由官方管道构建。 属实。结论，事后分析：SHIP IT。 两位维护者都在一天内发布了带有时间戳的事后分析；三天内， 下游管道使用ignore-scripts进行安装， 将构建与发布分离，并丢弃了长期存在的令牌。

### 影响范围

2:47 npm的默认设置尚未改变。 周一：安装时忽略脚本，并将发布令牌从运行它的作业中移除。 请在评论中或发送到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
