Mini Shai-Hulud:瞄准 AI 工具链的供应链蠕虫
2026 年 5 月 11 日至 18 日披露的 Mini Shai-Hulud 蠕虫污染了 170 多个 npm 与 PyPI 软件包——包括 Mistral AI、Guardrails AI 和 TanStack——并在 Claude Code 与 VS Code 中植入持久化。
发生了什么
2026 年 5 月 11 日,威胁行为者 TeamPCP 开始发布广泛使用的 npm 软件包的木马化版本,首先是 TanStack,随后在数小时内扩展到 Mistral AI 的 Python SDK、Guardrails AI、UiPath 和 OpenSearch。在五个小时内,超过 400 个恶意版本被发布到 172 个不同的软件包(npm 与 PyPI 合计),这些包累计历史下载量约 5.18 亿次。5 月 12 日,完全武器化的源代码被短暂发布到公开的 GitHub 仓库后被下架。从 5 月 18 日开始的第二波攻击,通过被劫持的维护者账号污染了 300 多个 @antv 软件包。该活动——以 2025 年末更大规模的 npm 蠕虫为参照被命名为 Mini Shai-Hulud——其 TanStack 初始向量已分配编号 CVE-2026-45321(CVSS 9.6)。
值得在本站单独成文的原因是:AI 工具栈是主要攻击目标,而非附带受害者。
工作原理
TanStack 入口串联了 GitHub Actions 的三处错误配置。攻击者以重命名后的账号 fork 目标仓库(用 zblgg/configuration 而不是 zblgg/router 以规避 fork 列表搜索),提交一个 pull request,触发 pull_request_target 工作流。该工作流在基础仓库的可信上下文中检出并执行攻击者 fork 的代码——可以访问 secrets、拥有 id-token: write 范围,并对 GitHub Actions 缓存有写权限。攻击者的 fork 携带一个被污染的 pnpm store 并被缓存;后续合法的 CI 运行会拉取这份被污染的缓存,并向 npm 发布带有合法 provenance 证明的木马化 tarball——因为发布确实来自官方流水线。
载荷本身是模块化的:
# 概念示意 —— 取自公开 IoC 分析,不可运行。
# 恶意 post-install:
# 1. 通过三条冗余通道将环境变量外泄到 C2。
# 2. 窃取:GITHUB_TOKEN、AWS IAM 密钥、HashiCorp Vault 令牌、K8s secrets。
# 3. 通过 id-token: write 伪造 OIDC 签名的 npm 发布令牌。
# 4. 部署 `gh-token-monitor` 服务以再次外泄轮换后的令牌。
# 5. 通过写入以下文件实现持久化:
# ~/.claude/settings.json # Claude Code 钩子
# ~/.vscode/tasks.json # VS Code task runner
# 6. 如果 api.github.com 返回 HTTP 40x(令牌被撤销):
# rm -rf ~/ # [破坏性载荷 —— 已涂黑]
针对 Mistral AI 和 Guardrails AI 的 PyPI 变体携带的是另一个 stealer,专为 Python 环境调整——相同的 C2、相同的外泄目标,但钩子不同。一周后的 @antv 浪潮使用的是被盗的维护者凭据,而非 CI 污染,但 post-install 载荷属于同一家族。
为什么重要
三点让这次活动不同于普通的 npm 供应链攻击。
AI 栈被纳入射程。 Guardrails AI 在设计上是 LLM 应用包裹在模型调用外的防御性库。被木马化的版本会把”护栏”翻转为外发的外泄通道,恰好位于应用与模型的边界上。Mistral AI 的 Python SDK 影响每一个调用 Mistral API 的项目。根据 Rescana 的分析,OpenAI 的 macOS 桌面产品通过 TanStack 的依赖链间接受到影响。
持久化专门针对 AI 智能体。 写入 ~/.claude/settings.json 可在 npm uninstall 之后存活,并在下一次启动 Claude Code 时重新激活 stealer。同样的模式适用于任何在启动时自动加载配置的智能体。智能体的特权范围——shell 访问、仓库访问、凭据访问——就此成为蠕虫的特权范围。
Provenance 证明是有效的。 由于发布发生在合法的 GitHub Actions 流水线中,npm 的 provenance 签名是通过的。仅依赖 provenance 证明的防御无法捕获此类攻击。
防御建议
此处没有模型侧缓解措施。修复方向是 CI/CD 卫生和凭据纪律。
- 审计 lockfile,排查 2026 年 4 月 29 日之后安装的任何受影响包版本。使用
npm audit、Snyk 或社区扫描器(GLPMC/Tanstack-Worm-Detector、omarpr/mini-shai-hulud-ioc-scanner)。任何命中都应视为已确认的事件。 - 轮换所有可从受感染工作站或 CI runner 访问的凭据:GitHub PAT 与 OAuth 令牌、npm 令牌、云 IAM 密钥(AWS/GCP/Azure)、HashiCorp Vault 令牌、Kubernetes 服务账号 secrets。
- 限制
pull_request_target。 在该触发器下绝不要在没有repository_owner守卫的情况下检出 fork 代码。将 fork 构建迁移到无 secrets 的pull_request。 - 按 SHA 锁定第三方 actions,不要按 tag。内部 action 的消费者也要锁定。
- 将
id-token: write限定到最小的 job,绝不在 workflow 层级声明。 - 清理 Claude Code 与 VS Code 中的持久化。 检查
~/.claude/settings.json与~/.vscode/tasks.json(以及它们在 workspace 中的副本),寻找您并未创建的钩子条目。IoC 扫描器会标记已知变体。 - 按分支重新划分 CI 缓存。 TanStack 的加固包括删除所有缓存并将 fork 构建隔离到 fork 侧。请采用相同模式。
状态
| 目标 | 攻击向量 | 披露日期 | 修复 / 清理 |
|---|---|---|---|
TanStack(@tanstack/*) | 通过 pull_request_target 进行 CI 缓存污染 | 2026-05-11 | 恶意版本下架;CI 重构 |
| Mistral AI Python SDK | PyPI 发布被木马化 | 2026-05-11 | 受影响版本撤回,重新发布新版本 |
| Guardrails AI | PyPI 发布被木马化 | 2026-05-11 | 受影响版本撤回 |
| UiPath、OpenSearch-js | npm 发布被木马化 | 2026-05-11 | 已下架 |
@antv/*(300+ 软件包) | 维护者账号被攻陷 | 2026-05-18 | 维护者重置,软件包已清理 |
| CVE-2026-45321(TanStack CI 链) | — | 2026-05-12 | CVSS 9.6 —— 已发布缓解措施 |
更深层的启示:AI 工具栈本身已成为高价值的供应链攻击目标。一条落在 ~/.claude/settings.json 中的蠕虫不需要攻破模型——它已经拥有了智能体。
Sources
- → https://thehackernews.com/2026/05/mini-shai-hulud-worm-compromises.html
- → https://www.wiz.io/blog/mini-shai-hulud-strikes-again-tanstack-more-npm-packages-compromised
- → https://snyk.io/blog/tanstack-npm-packages-compromised/
- → https://www.tenable.com/blog/mini-shai-hulud-frequently-asked-questions
- → https://labs.cloudsecurityalliance.org/research/csa-research-note-shai-hulud-ai-supply-chain-20260517-csa-st/
- → https://expel.com/blog/mini-shai-hulud-cross-ecosystem-supply-chain-worm-targeting-npm-pypi/
- → https://www.aikido.dev/blog/mini-shai-hulud-antv-npm-supply-chain-attack