← EasyTool.me

TanStack npm 供应链攻击 — Mini Shai-Hulud 蠕虫回归

发布日期:2026-05-12 阅读时间:6 分钟 安全 / 供应链攻击

事件概述

2026年5月11日,一个名为 Mini Shai-Hulud 的自传播蠕虫攻破了 TanStack npm 生态系统。TanStack 是 React 生态中最广泛使用的路由库之一,每周下载量达数百万次。攻击者向 40 多个 @tanstack 包注入了 2.3MB 的混淆凭证窃取 payload,并通过劫持的 OIDC token 利用项目自身的 GitHub Actions 发布管线发布了恶意版本。

这次事件的历史意义在于:它是 首个携带有效 SLSA 来源证明的自传播 npm 蠕虫。这些恶意包看起来完全合法——因为它们确实是由真实管线发布的。蠕虫继承了 TanStack 的可信发布者身份。

攻击首先由 StepSecurity 通过其 OSS Package Security Feed 实时检测到并披露。GitHub Issue #7383 被创建以通知维护者,该事件迅速登上 Hacker News 首页

攻击链详解

第一步:Fork 并准备载荷

攻击者于 2026年5月10日创建了 TanStack/router 的 Fork,推送了一个包含伪造 @tanstack/setup 包的 commit(79ac49ee)。该包的 prepare 生命周期钩子会运行 bun run tanstack_runner.js && exit 1 —— 末尾的 && exit 1 是故意的,让可选依赖"优雅地失败",在日志中留下极少痕迹,而此时 payload 已经执行完毕。

第二步:注入已发布的包

每个被投毒的包都被做了两处修改:

结果:被投毒的 tarball 比正常版本大 3.7 倍(905 KB vs 190 KB),多出 23 个文件。

第三步:通过合法管线发布

恶意包携带了绑定到真实 TanStack Release 工作流的 有效 SLSA 来源证明。攻击者利用工作流的环境 id-token: write OIDC token 直接发布到 npm —— 绕过了工作流自身的发布步骤,即使"Run Tests"步骤已经失败。

关键洞察:SLSA 来源证明只能确认制品是哪条管线生产的,无法确认管线的行为是否符合预期。被劫持的构建步骤可以产出拥有有效签名的恶意包。

Payload 分析:它窃取什么

router_init.js payload 使用了多层混淆:

Payload 包含 10 个专用收集器类,从多个来源采集密钥。它读取 GitHub Actions 环境变量(GITHUB_WORKFLOW_REFGITHUB_REPOSITORY 等)来识别高价值目标。它导入了 child_processfscryptoos —— 赋予它任意命令执行、文件系统访问和加密签名能力。

窃取的凭证通过 HTTPS(443 端口)以缓冲调度系统发送到攻击者控制的服务器,包含多个备用发送通道。

自传播机制:蠕虫如何扩散

Mini Shai-Hulud 最危险的特性是 自主传播。收集到 token 后,蠕虫会遍历发现的 GitHub token,用它们来:

  1. 向 npm 注册表或 GitHub API 认证
  2. 识别该 token 有写权限的其他包
  3. 向这些包注入相同的恶意 payload
  4. 发布新的被投毒版本

这个传播循环解释了为什么攻击扩散到了 TanStack 之外的包——@uipath(8个包)、@draftauth@draftlab@taskflow-corp@tolka 等——蠕虫跟着窃取到的凭证走到哪里就感染到哪里。

受影响的包(部分列表)

@tanstack 生态 —— react-router、router-core、react-start、solid-router、vue-router、history、router-plugin 等数十个。每个包都收到了两个被投毒的版本("双重打击"模式)。

其他组织 —— @uipath(8个包,包括 agent.sdk、filesystem、admin-tool)、@draftauth(client、core)、@draftlab(auth、auth-router、db)、@taskflow-corp/cli、@tolka/cli。

完整列表在 StepSecurity OSS Security Feed 持续更新。

我是否受影响?

检查你的 Lockfile

grep "@tanstack/" package-lock.json | grep -v node_modules
grep -E "(draftlab|draftauth|taskflow-corp|tolka)" package-lock.json pnpm-lock.yaml yarn.lock 2>/dev/null

将解析出的版本与 StepSecurity 列出的被投毒版本进行交叉比对。

检查恶意文件

find node_modules -name "router_init.js" -type f 2>/dev/null
grep -r "@tanstack/setup" node_modules/*/package.json 2>/dev/null

检测信号

恢复步骤

个人开发者

  1. 锁定到安全版本 —— 降级到每个受影响包的最后一个干净版本
  2. 删除并重装 —— rm -rf node_modules && npm install
  3. 轮转凭证 —— 该机器上可访问的所有 npm token、GitHub PAT 和云 API 密钥
  4. 检查 ~/.npmrc —— 蠕虫会读取主目录密钥,审查并轮转存储的 token

CI/CD 环境(紧急)

  1. 立即轮转所有 CI 密钥 —— GitHub token、npm token、云服务商凭证及工作流环境中可访问的所有密钥
  2. 审计 GitHub Actions 运行记录 —— 审查 2026-05-11T19:20Z 之后的运行,查找意外的 npm publish 事件
  3. 检查下游传播 —— 如果你的任何包是在安装了被投毒版本的 CI 运行中发布的,那些版本可能也被感染了
  4. 审查 npm access token —— 运行 npm token list 并撤销不认识的 token

如何防御 CI/CD 蠕虫攻击

入侵指标(IoC)

SHA-256 哈希:

攻击者基础设施:

总结

Mini Shai-Hulud 攻击暴露了 npm 生态信任模型的根本缺陷。来源证明只能确认制品是在哪里构建的,无法确认构建了什么。一条攻破 CI/CD 管线的蠕虫会继承管线的全部身份——OIDC token、SLSA 签名、可信发布者状态。从注册表的角度看,恶意发布和合法发布完全无法区分。

关键要点:

来源:StepSecurity — Mini Shai-Hulud Is Back | GitHub Issue #7383 | Hacker News 讨论