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供应链蠕虫攻击的技术拆解 |
Fireship在视频开篇就点明了这次攻击的震撼之处——仅用6分钟,从19:20到19:26 UTC,攻击者在42个@tanstack包中发布了84个恶意版本。但TanStack只是冰山一角。根据Aikido、Snyk、Akamai等多家安全公司的后续调查,实际波及范围包括:
总计170+个包被感染。这不是一个手工操作的攻击者能完成的——这是一条自动化蠕虫。Fireship在视频中强调了攻击的速度和规模,这也是Mini Shai-Hulud名称的由来:比2025年9月的原始Shai-Hulud更"mini"(轻量)、更快、更自动化。
延伸分析:5个月内的第5波攻击,每一波都在扩大攻击面。原始Shai-Hulud影响了526个库,而Mini版本虽然单次规模更小,但传播效率更高,攻击间隔更短。这说明TeamPCP在持续迭代其攻击工具链。
这是整个事件最令人细思极恐的部分。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配置不当,蠕虫就会跳到下一个组织,继续传播。
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机制是一个极具讽刺意味的攻击向量——这个机制本来是为了提高发布安全性而设计的,却被攻击者反向利用了。
Fireship在视频中专门提到TanStack并非随机选择。原因很明确:
@tanstack/react-query周下载量超过600万,@tanstack/react-table也不遑多让。这是React生态的"基础设施级"依赖。延伸分析:这揭示了一个令人不安的悖论——开源项目越是做得好(自动化CI/CD、积极响应PR、Trusted Publishing),反而越容易成为目标。这不是TanStack的错,而是整个npm生态信任架构的根本性缺陷。
攻击发生后,安全社区的响应速度相当快:
AWS_ACCESS_KEY_ID、GITHUB_TOKEN等环境变量。延伸分析:Microsoft的报告揭示了一个更深层的威胁——这些被窃取的CI/CD凭证如果落入攻击者手中,可能被用来进一步攻击依赖这些凭证的云基础设施。供应链攻击的影响绝不限于"npm包被污染"这么简单,它可能成为企业云环境全面沦陷的入口。
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"水平不亚于一流的开发团队。
这是整个事件的核心技术争议点。npm的postinstall、preinstall脚本机制允许包在安装时自动执行任意代码。这个功能有其正当用途(比如编译native模块),但它同时也是:
npm install都是一次对数千个陌生人的无条件信任Fireship在视频中暗示npm应该默认禁用lifecycle scripts,但这引发了另一个问题——大量现有的构建工具链依赖这个功能。Node.js社区围绕--ignore-scripts flag的争论已经持续多年。
延伸分析:Deno和Bun在这方面做了一些改进——Deno默认不允许包执行任意脚本,Bun虽然在本次攻击中被攻击者利用,但其包管理器也提供了更细粒度的权限控制。但这些改进对于npm已有的数百万个项目来说,已经太迟了。
Trusted Publishing是npm和PyPI近年来推出的安全功能,通过OIDC(OpenID Connect)token实现CI/CD环境的无密钥发布。理论上,这比维护者手动管理npm token更安全——token不会被泄露,因为它只在CI环境中短期存在。
但TeamPCP的攻击揭示了这个设计的一个致命盲区:如果CI环境本身被污染(通过恶意PR触发),那从"受信任的CI环境"中生成的OIDC token自然也是不可信的。
这就像一个银行金库的安保系统——密码没有泄露,但进入金库的人本身就是伪装的。
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悖论
开源维护者安全意识
立即检查你的依赖:运行npm audit和npx npm-check,确认没有安装被感染的版本号(参考Snyk和npm官方公告中的具体版本列表)。如果你的package-lock.json中包含2026年5月11-12日发布的@tanstack版本,立即回退到此前版本。
在项目中启用--ignore-scripts:在你的.npmrc中加入ignore-scripts=true,这样npm install时不会自动执行任何lifecycle scripts。如果你确实需要某些包的脚本(如native模块编译),使用npm rebuild手动触发。
审查你的CI/CD配置:检查你的GitHub Actions workflow是否在PR触发时执行了npm install或npm publish。如果PR触发的workflow中有publish步骤,立即改为仅main branch触发。
使用lockfile并验证完整性:永远不要运行npm update而不检查变更内容。package-lock.json是你对抗供应链攻击的第一道防线。
最小化CI环境变量权限:不要在CI环境中存储不必要的token。如果某个workflow不需要发布权限,就不要给它。
一个PR触发CI/CD → 生命周期脚本窃取凭证 → 6分钟投毒170+个包 → 自我传播到更多组织——这不是科幻,这是2026年npm供应链的残酷现实,它迫使每一位开发者重新审视"我到底信任了谁"。
本文由「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 等场景全覆盖。
