curl -fsSL https://raw.githubusercontent.com/nkopylov/tanscript-exploit-check/main/check-tanstack-exploit.sh | bash
或者克隆并在本地运行:
git clone https://github.com/nkopylov/tanscript-exploit-check.git
cd tanscript-exploit-check
./check-tanstack-exploit.sh [project_dir ...]
此检查器覆盖了由 TeamPCP 发起的 Mini Shai-Hulud 供应链攻击活动的两波攻击:
2026 年 5 月 11 日(19:20-19:26 UTC),攻击者在 6 分钟内发布了 42 个 @tanstack/* npm 包中的 84 个恶意版本。此次攻击还波及了 Mistral AI、UiPath、OpenSearch 等公司的包——npm 和 PyPI 上总计超过 170 个包。
没有任何维护者凭据被盗。 攻击者通过 3 阶段攻击利用了 CI/CD 信任链本身:
pull_request_target 漏洞利用 —— 一个一次性 GitHub fork 发起了 PR,在基础仓库的安全上下文中运行了攻击者代码2026 年 5 月 19 日(01:39-02:06 UTC),被入侵的 atool npm 账户([email protected])通过两轮自动化攻击发布了 314 个包中的 637 个恶意版本。影响较大的目标包括:
size-sensor(每月 420 万次下载)echarts-for-react(每月 380 万次下载)@antv/scale(每月 220 万次下载)timeago.js(每月 115 万次下载)@antv/* 及其他包该波攻击使用了基于 Bun 的载荷(498KB 的 index.js),通过 "preinstall": "bun run index.js" 触发,第二阶段载荷隐藏在伪造提交中,利用 fork 对象共享漏洞推送至 antvis/G2 GitHub 仓库。
两波攻击使用相同的 "Mini Shai-Hulud" 工具包家族:
gh-token-monitor(第一波)和 kitty-monitor(第二波)守护进程;在 .claude/settings.json 和 .vscode/tasks.json 中注入钩子toJSON(secrets)、npm OIDC 令牌交换rm -rf ~/firedalazer 关键字,使用 RSA-PSS 签名的命令只有 @tanstack/router* 和 @tanstack/start* 受影响。不受影响: @tanstack/query*、@tanstack/table*、@tanstack/form*、@tanstack/virtual*、@tanstack/store。
查看 完整安全公告 了解全部 42 个包。
npm 用户 atool([email protected])发布的所有包在 2026 年 5 月 19 日都收到了恶意版本。影响较大的包包括:
| 包 | 每月下载量 |
|---|---|
size-sensor | 420 万 |
echarts-for-react | 380 万 |
@antv/scale | 220 万 |
timeago.js |
此外还有 310+ 个包,主要位于 @antv/* 作用域内(@antv/g2、@antv/g6、@antv/l7、@antv/s2、@antv/x6、@antv/f2 等),以及 ai-figure、timeago-react、jest-canvas-mock、jest-date-mock 等。
查看 SafeDep 分析文章 获取完整列表。
关键:在撤销任何令牌之前,先禁用死亡开关。 如果守护进程活跃期间令牌被撤销,恶意软件会清空
$HOME。
gh-token-monitor 和 kitty-monitor),并删除 LaunchAgent/systemd 服务.claude/router_runtime.js、.vscode/setup.mjs、~/.local/share/kitty/cat.py、/var/tmp/.gh_update_state 等)node_modules 和锁文件,使用 --ignore-scripts 重新安装api.masscan.cloud、filev2.getsession.org、git-tanstack.com、t.m-kosche.com)将以下提示词复制粘贴到你的 AI 编程代理(Claude Code、Cursor、Cline/OpenClaw、Windsurf、Hermes 等)中,以加固你的项目,防范此类供应链攻击。
加固此项目的 npm 配置以防范供应链攻击。请执行以下操作:
锁定精确版本:移除
package.json中所有依赖项前面的^和~前缀,确保npm install永远不会静默拉取新发布的版本。默认禁用 postinstall 脚本:在
.npmrc中添加ignore-scripts=true。然后在package.json中添加一个显式的"preinstall"脚本,仅运行此项目实际需要的已知安全生命周期脚本(如有)。在 CI 中强制仅使用锁文件安装:确保 CI 使用
npm ci(而非npm install)。如果存在 CI 配置文件,请核实。如果没有,请将其记为手动步骤。添加来源验证:在 CI 流水线中以及作为 pre-push git 钩子添加
npm audit signatures步骤。创建更新策略脚本:创建一个
scripts/safe-update.sh,其功能如下:
审计并加固此项目的 AI 编程代理配置,以防范供应链注入攻击(例如 TanStack/Mini Shai-Hulud 活动中向
.claude/settings.json和.vscode/tasks.json注入恶意钩子的手法)。请执行以下操作:Claude Code(
.claude/):
- 检查
.claude/settings.json和.claude/settings.local.json中是否有运行 shell 命令的hooks条目。标记任何执行.js、.mjs或.sh文件的内容——尤其是位于.claude/、.vscode/或node_modules/目录内的。- 移除任何无法追溯到合法、用户创建用途的钩子。
- 添加一条
.gitignore规则,防止.claude/settings.local.json被提交(它应保持本地状态)。
审计并加固此仓库中的 GitHub Actions 配置,以防范 CI/CD 供应链攻击。请执行以下操作:
移除或重构所有
pull_request_target触发器 —— 即使在 fork 触发时,这些触发器也会在基础仓库的上下文中运行工作流代码并可访问机密。如有需要,请替换为pull_request加单独的审批门控工作流。将所有第三方 action 固定到完整提交 SHA(而非标签或分支)。例如,将
actions/checkout@v4替换为actions/checkout@<full-sha>。添加包含标签的注释以提高可读性。为每个工作流应用最小权限。添加显式的
permissions:块。大多数工作流只需要contents: read。发布工作流需要id-token: write——仅此而已。限制缓存范围:如果使用
actions/cache,请确保缓存键按分支限定范围,以防跨分支投毒。谨慎添加restore-keys——不要从未受信任的分支恢复缓存。在每个作业的第一步添加 StepSecurity Harden-Runner:
step-security/harden-runner@v2,并设置egress-policy: audit(如果你知道允许的端点,可设为 )。
MIT
| # | 检查项 | 描述 |
|---|
| 1 | 死亡开关 | 持久化守护进程:gh-token-monitor(第一波)、kitty-monitor(第二波) |
| 2 | 恶意进程 | 已知攻击者进程名(两波) |
| 3 | 载荷文件 | 按文件名和 SHA-256 哈希(4 个哈希)识别的已知恶意文件 |
| 4 | Claude Code 钩子 | 注入到 .claude/settings.json 的钩子 + 通用 SessionStart 启发式检测 |
| 5 | VS Code 任务 | 注入到 .vscode/tasks.json 的任务 + 通用 runOn: folderOpen 启发式检测 |
| 6 | GitHub Actions | 任意工作流中的 toJSON(secrets) + pull_request_target 警告 |
| 7 | npm 锁文件 | 锁文件中的受损包版本 |
| 8 | optionalDependencies | 恶意 @tanstack/setup 和 @antv/setup + 4 个伪造提交 SHA |
| 9 | 网络连接 | 与 C2 基础设施的活动连接(5 个域名/IP) |
| 10 | DNS 缓存 | 先前解析的攻击者域名(4 个域名) |
| 11 | Git 分支 | 沙丘主题的攻击者分支命名模式 |
| 12 | 生命周期脚本 | 启发式: preinstall/postinstall 中的 bun run(已安装的包) |
| 13 | 死信箱 C2 | git 历史中的 firedalazer 关键字和 "Shai-Hulud" 标记 |
| 14 | GitHub 依赖 | 启发式: optionalDeps 中固定到提交 SHA 的 github: 依赖 |
| 包 | 恶意版本 | 首个安全版本 |
|---|
@tanstack/react-router | 1.169.5, 1.169.8 | 1.169.9 |
@tanstack/router-core | 1.169.5, 1.169.8 | 1.169.9 |
@tanstack/vue-router | 1.169.5, 1.169.8 | 1.169.9 |
@tanstack/solid-router | 1.169.5, 1.169.8 | 1.169.9 |
@tanstack/react-start | 1.167.68, 1.167.71 | 1.167.72 |
@tanstack/router-plugin | 1.167.38, 1.167.41 | 1.167.42 |
| 115 万 |
npm view <pkg> time --json)npm install <pkg>@latest --save-exact不要修改任何应用程序代码。只修改配置文件、.npmrc、package.json 脚本和 CI 配置。
VS Code(.vscode/):
.vscode/tasks.json 和 .vscode/launch.json 中是否有执行意外脚本或二进制文件的任务。setup.mjs、router_runtime.js 等不属于此项目的文件名的任务条目。.vscode/extensions.json 中是否有你不认识的扩展。Cursor(.cursor/):
.cursor/settings.json 及任何规则文件中是否含有注入的命令或钩子。.vscode/ 配置。通用:
package.json 中是否有非你本人编写的 preinstall、postinstall、prepare 或 prestart 脚本,并标记可疑项。.github/workflows/ 中是否有使用 pull_request_target 的工作流——将其标记为安全风险,并添加注释说明原因。.gitignore 排除了可能泄露凭据的代理会话文件(.claude/projects/、.cursor/logs/ 等)。报告你的发现和所做的更改。不要修改应用程序代码。
block检查工作流日志中的机密:确保没有工作流步骤向 stdout 打印 ${{ secrets.* }} 或 ${{ toJSON(secrets) }}。
报告所有更改。不要修改应用程序代码。