<!-- title: 一个PR如何劫持整个NPM生态 -->
<!-- domain: programming -->
<!-- video: https://www.youtube.com/watch?v=gwTQLZSIlsU -->

# 一个PR如何劫持整个NPM生态：Mini Shai-Hulud供应链攻击全解析

2026年5月11日，北京时间凌晨3点20分，一个名叫TeamPCP的黑客组织用6分钟时间向npm注册表投毒84个包，波及TanStack、OpenSearch、Mistral AI、UiPath等170多个知名项目。这不是又一起"开发者密码泄露"的老套路——攻击者靠的是**一个Pull Request**，就撬开了整个npm供应链的信任锁链。Fireship频道在3天后发布的视频"A single PR just hijacked the NPM registry..."，用不到7分钟把这个事件讲得清清楚楚。4.2M订阅的开发者顶流频道、极其时效性的话题、直接关乎每一位Node.js开发者的日常工作——这就是本期深度解读的视频。

## 视频背景卡片

| 项目 | 内容 |
|------|------|
| 视频标题 | A single PR just hijacked the NPM registry... |
| 频道 | Fireship |
| 时长 | 约7分钟 |
| 播放量 | 发布数日内迅速攀升（Fireship频道总播放超7亿） |
| 发布日期 | 2026年5月14日 |
| 核心主题 | Mini Shai-Hulud npm供应链蠕虫攻击的技术拆解 |

## 核心内容拆解

### 1. 六分钟的精确打击：时间线还原

Fireship在视频开篇就点明了这次攻击的震撼之处——**仅用6分钟**，从19:20到19:26 UTC，攻击者在42个`@tanstack`包中发布了84个恶意版本。但TanStack只是冰山一角。根据Aikido、Snyk、Akamai等多家安全公司的后续调查，实际波及范围包括：

- **@tanstack** — 前端生态核心库（Table、Query、Router、Form等42个包）
- **@opensearch-project** — 开源搜索引擎
- **@mistralai** — 欧洲顶级AI公司的官方SDK
- **@uipath** — RPA行业巨头
- **@antv** — 蚂蚁集团数据可视化库（Microsoft后续确认）
- **@squawk** 及其他开源组织

总计**170+个包**被感染。这不是一个手工操作的攻击者能完成的——这是一条**自动化蠕虫**。Fireship在视频中强调了攻击的速度和规模，这也是Mini Shai-Hulud名称的由来：比2025年9月的原始Shai-Hulud更"mini"（轻量）、更快、更自动化。

**延伸分析**：5个月内的第5波攻击，每一波都在扩大攻击面。原始Shai-Hulud影响了526个库，而Mini版本虽然单次规模更小，但传播效率更高，攻击间隔更短。这说明TeamPCP在持续迭代其攻击工具链。

### 2. 攻击机制：一个PR如何变成核弹

这是整个事件最令人细思极恐的部分。Fireship在视频中用标志性的高密度讲解风格，拆解了攻击链：

**Step 1：投毒CI/CD缓存。** 攻击者向目标仓库提交一个看似正常的Pull Request。这个PR本身不包含任何恶意代码——它只是触发了CI/CD流水线。

**Step 2：利用npm生命周期脚本。** 当CI/CD流水线运行`npm install`或`npm publish`时，恶意payload通过`preinstall`、`postinstall`等lifecycle scripts被激活。这是npm设计中一个长期被诟病的安全隐患。

**Step 3：窃取发布凭证。** 恶意脚本从CI环境变量中提取npm publish token，或者直接利用GitHub Trusted Publishing的OIDC token。

**Step 4：自动发布恶意版本。** 蠕虫用窃取的凭证，自动向npm注册表发布被感染的包版本。

**Step 5：自我传播。** 被感染的包在下游用户安装时再次执行lifecycle scripts，如果受害者也是npm包维护者且CI/CD配置不当，蠕虫就会跳到下一个组织，继续传播。

```mermaid
flowchart TD
    A[攻击者提交恶意PR] --> B[目标仓库CI/CD被触发]
    B --> C[npm install 执行 postinstall 脚本]
    C --> D[恶意脚本窃取 CI/CD 凭证]
    D --> E[利用 Bun 运行时加载远端 payload]
    E --> F[自动发布 84 个被感染包版本]
    F --> G[下游开发者 npm install 被感染包]
    G --> H{受害者也是包维护者?}
    H -->|是| I[蠕虫跳转到新组织]
    I --> B
    H -->|否| J[窃取本地环境变量和密钥]

    style A fill:#e74c3c,color:#fff
    style F fill:#e74c3c,color:#fff
    style J fill:#f39c12,color:#fff
```

**延伸分析**：这次攻击的一个关键技术细节是使用了**Bun运行时**而非Node.js来执行恶意payload。Phoenix Security的分析指出，Bun的引入可能是为了绕过一些基于Node.js行为特征的安全检测工具。同时，利用GitHub Trusted Publishing的OIDC机制是一个极具讽刺意味的攻击向量——这个机制本来是为了**提高**发布安全性而设计的，却被攻击者反向利用了。

### 3. 为什么TanStack成为首选目标

Fireship在视频中专门提到TanStack并非随机选择。原因很明确：

- **超高下载量**：`@tanstack/react-query`周下载量超过600万，`@tanstack/react-table`也不遑多让。这是React生态的"基础设施级"依赖。
- **积极的CI/CD配置**：TanStack项目采用GitHub Actions自动化发布流程，且维护者对社区PR响应迅速——这本是优秀开源实践的标志，却被攻击者利用。
- **Trusted Publishing配置**：TanStack使用了npm的Trusted Publishing功能（通过OIDC token），攻击者精准利用了这个信任链。
- **多包仓库架构**：TanStack采用monorepo结构，一个CI/CD配置影响数十个子包，放大了单次入侵的影响面。

**延伸分析**：这揭示了一个令人不安的悖论——**开源项目越是做得好（自动化CI/CD、积极响应PR、Trusted Publishing），反而越容易成为目标**。这不是TanStack的错，而是整个npm生态信任架构的根本性缺陷。

### 4. 微软、Snyk、Akamai的联合响应

攻击发生后，安全社区的响应速度相当快：

- **Snyk** 在攻击发生后数小时内发布告警，追踪到84个恶意版本的具体版本号和hash值。
- **Akamai Security Intelligence Group** 于5月15日发布深度分析，确认攻击者通过CI cache poisoning获取了发布凭证。
- **Microsoft Defender** 在5月20日确认@antv也被感染，并发现恶意包会专门针对Linux CI环境窃取`AWS_ACCESS_KEY_ID`、`GITHUB_TOKEN`等环境变量。
- **npm官方** 在事件发生后数小时内yank了所有被感染版本，并暂时吊销了受影响组织的发布凭证。

**延伸分析**：Microsoft的报告揭示了一个更深层的威胁——这些被窃取的CI/CD凭证如果落入攻击者手中，可能被用来进一步攻击依赖这些凭证的云基础设施。供应链攻击的影响绝不限于"npm包被污染"这么简单，它可能成为企业云环境全面沦陷的入口。

### 5. Shai-Hulud的前世今生：五波攻击的进化史

Fireship的视频聚焦于最新一波攻击，但理解完整背景才能看清趋势：

| 波次 | 时间 | 规模 | 关键特征 |
|------|------|------|----------|
| 第1波 | 2025年9月 | 526个包 | 原始Shai-Hulud，首次展示npm蠕虫概念 |
| 第2波 | 2025年11月 | ~200个包 | 改进传播机制，引入CI cache poisoning |
| 第3波 | 2026年1月 | ~180个包 | 针对axios等超级包的定向攻击（RAT植入） |
| 第4波 | 2026年4月 | ~160个包 | Mini版本首次出现，引入Bun运行时 |
| 第5波 | 2026年5月 | 170+个包 | 本波攻击，TanStack+OpenSearch+Mistral AI |

**延伸分析**：每一波攻击的核心改进方向是"更快、更轻、更自动化"。从第1波需要手动部分操作，到第5波完全自动化的6分钟投毒。攻击者的迭代速度令人担忧——他们的"DevOps"水平不亚于一流的开发团队。

### 6. npm生命周期脚本：一个"设计缺陷"还是"必要之恶"

这是整个事件的核心技术争议点。npm的`postinstall`、`preinstall`脚本机制允许包在安装时自动执行任意代码。这个功能有其正当用途（比如编译native模块），但它同时也是：

- 每一次`npm install`都是一次对数千个陌生人的**无条件信任**
- 一个被感染的间接依赖可以在你毫不知情的情况下执行恶意代码
- 即使你信任了直接依赖的维护者，你也无法信任他们依赖的所有上游包

Fireship在视频中暗示npm应该默认禁用lifecycle scripts，但这引发了另一个问题——大量现有的构建工具链依赖这个功能。Node.js社区围绕`--ignore-scripts` flag的争论已经持续多年。

**延伸分析**：Deno和Bun在这方面做了一些改进——Deno默认不允许包执行任意脚本，Bun虽然在本次攻击中被攻击者利用，但其包管理器也提供了更细粒度的权限控制。但这些改进对于npm已有的数百万个项目来说，已经太迟了。

### 7. GitHub Trusted Publishing的信任悖论

Trusted Publishing是npm和PyPI近年来推出的安全功能，通过OIDC（OpenID Connect）token实现CI/CD环境的无密钥发布。理论上，这比维护者手动管理npm token更安全——token不会被泄露，因为它只在CI环境中短期存在。

但TeamPCP的攻击揭示了这个设计的一个致命盲区：**如果CI环境本身被污染（通过恶意PR触发），那从"受信任的CI环境"中生成的OIDC token自然也是不可信的**。

这就像一个银行金库的安保系统——密码没有泄露，但进入金库的人本身就是伪装的。

## 知识结构图

```mermaid
mindmap
  root((Mini Shai-Hulud\nnpm供应链攻击))
    攻击技术
      CI/CD缓存投毒
      npm生命周期脚本利用
      Bun运行时加载payload
      GitHub OIDC Token窃取
      自动化蠕虫传播
    受影响生态
      TanStack（42个包）
      OpenSearch
      Mistral AI SDK
      UiPath
      antv（蚂蚁集团）
    防御措施
      npm --ignore-scripts
      锁定依赖版本（lockfile）
      CI/CD环境变量最小化
      发布冷却期机制
      自动化安全扫描
    深层问题
      npm信任模型缺陷
      间接依赖不可控
      Trusted Publishing悖论
      开源维护者安全意识
```

## 实战启示

### 如果你是一名前端/Node.js开发者

1. **立即检查你的依赖**：运行`npm audit`和`npx npm-check`，确认没有安装被感染的版本号（参考Snyk和npm官方公告中的具体版本列表）。如果你的`package-lock.json`中包含2026年5月11-12日发布的`@tanstack`版本，立即回退到此前版本。

2. **在项目中启用`--ignore-scripts`**：在你的`.npmrc`中加入`ignore-scripts=true`，这样npm install时不会自动执行任何lifecycle scripts。如果你确实需要某些包的脚本（如native模块编译），使用`npm rebuild`手动触发。

3. **审查你的CI/CD配置**：检查你的GitHub Actions workflow是否在PR触发时执行了`npm install`或`npm publish`。如果PR触发的workflow中有publish步骤，**立即改为仅main branch触发**。

4. **使用lockfile并验证完整性**：永远不要运行`npm update`而不检查变更内容。`package-lock.json`是你对抗供应链攻击的第一道防线。

5. **最小化CI环境变量权限**：不要在CI环境中存储不必要的token。如果某个workflow不需要发布权限，就不要给它。

### 如果你是开源维护者

- 在npm Trusted Publishing配置中添加**发布冷却期**（cooldown period），新版本发布前等待数分钟，给自己一个"后悔"的窗口。
- 对外部PR触发的CI workflow，禁止任何写操作。
- 考虑使用Snyk、Socket等工具对你的发布流程进行实时监控。

### 延伸学习路径

1. **Snyk原始分析**：[TanStack npm Packages Hit by Mini Shai-Hulud](https://snyk.io/blog/tanstack-npm-packages-compromised/) — 最及时的技术细节
2. **Akamai深度研究**：[Mini Shai-Hulud: The Worm Returns and Goes Public](https://www.akamai.com/blog/security-research/mini-shai-hulud-worm-returns-goes-public) — CI cache poisoning机制详解
3. **Microsoft安全博客**：[Compromised @antv npm packages enable CI/CD credential theft](https://www.microsoft.com/en-us/security/blog/2026/05/20/mini-shai-hulud-compromised-antv-npm-packages-enable-ci-cd-credential-theft/) — 最新一波的影响范围
4. **Phoenix Security全谱分析**：[TeamPCP's Self-Propagating npm Worm](https://phoenix.security/mini-shai-hulud-teampcp-tanstack/) — 170个包的完整受影响列表
5. **Fireship频道**：[@Fireship on YouTube](https://www.youtube.com/@Fireship) — 持续关注最新的开发者安全动态

## 一句话总结

一个PR触发CI/CD → 生命周期脚本窃取凭证 → 6分钟投毒170+个包 → 自我传播到更多组织——这不是科幻，这是2026年npm供应链的残酷现实，它迫使每一位开发者重新审视"我到底信任了谁"。

## 参考来源

1. [A single PR just hijacked the NPM registry... - Fireship](https://www.youtube.com/watch?v=gwTQLZSIlsU) — 分析的核心视频
2. [TanStack npm Packages Hit by Mini Shai-Hulud - Snyk](https://snyk.io/blog/tanstack-npm-packages-compromised/) — 首发技术分析
3. [Mini Shai-Hulud: The Worm Returns and Goes Public - Akamai](https://www.akamai.com/blog/security-research/mini-shai-hulud-worm-returns-goes-public) — CI缓存投毒机制
4. [Compromised @antv npm packages - Microsoft Security Blog](https://www.microsoft.com/en-us/security/blog/2026/05/20/mini-shai-hulud-compromised-antv-npm-packages-enable-ci-cd-credential-theft/) — 最新影响范围扩展
5. [TeamPCP's Self-Propagating npm Worm - Phoenix Security](https://phoenix.security/mini-shai-hulud-teampcp-tanstack/) — 170个包完整分析

---
> 本文由「51学通信」技术团队出品。51学通信由通信行业18年老兵**爱卫生**（微信ID: gprshome201101）维护，聚焦5G/6G核心网、3GPP标准解读、通信前沿技术深度分析。
> 出版作品有《5G核心网原理与实践》《IMS原理与实践》等4本通信专业书籍。知识星球「51学通信」提供深度技术答疑和行业洞察。

> [!tip] 51学通信知识星球
> **星主：爱卫生**（微信：gprshome201101）——公众号「51学通信」创办者，19 年通信行业运维与讲师经验，著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书（各大电商平台有售）。
> **星球定位**：深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域，主打运维岗位与信令分析。
> **当前规模**：5200 篇主题 / 990 个回答，198 元/年。
> **加入福利**：加入星球后请加爱卫生微信，拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题，另有群内分享。
> **AI 加持**：51学通信知识星球已作为 skill 接入 WorkBuddy，使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例，做总结、找文档和 PPT 等场景全覆盖。

![51学通信知识星球海报-扫码加入](https://wiki.500nian.com/images/zhixingqiu_qrcode.png)
