概述

项目 内容
CVE ID CVE-2026-45321
GHSA GHSA-g7cv-rxg3-hmpx
披露时间 2026年5月11日 19:20-19:26 UTC
攻击手法 GitHub Actions OIDC 信任publisher绑定 + pull_request_target 错误配置 + 运行时内存提取
影响包数量 42个 @tanstack/* 包,共84个恶意版本
恶意代码 约2.3MB混淆的 router_init.js
窃取目标 云凭据、SSH密钥、GitHub Token、npm Token

攻击时间线

时间 事件
2026-05-11 19:20 UTC 攻击者开始向42个 @tanstack/* 包推送恶意版本
2026-05-11 19:26 UTC 推送完成,共84个恶意版本上线
2026-05-11 晚 安全社区发现并报告
2026-05-11 夜间 npm 紧急下架,TanStack 发布修复版本

攻击链分析

这次攻击不是简单的"攻击者拿到了 npm token",而是一个精心设计的三重漏洞链:

第一重:pull_request_target “Pwn Request” 错误配置

GitHub Actions 的 pull_request_target 触发器会在来自 fork 的 PR 中执行工作流,但这个工作流运行在基础仓库(target仓库)的上下文中,具有写权限。

正常配置应该是只信任已审核的 PR,但很多项目错误地配置为:pull_request_target 触发后,直接在有权限的上下文中执行来自 PR 的代码。

第二重:GitHub Actions 缓存投毒

攻击者利用 fork 与 base 仓库之间的信任边界,通过向合法仓库提交 PR 的方式,将恶意代码注入 Actions 缓存。当有权限的 CI 环境拉取缓存时,恶意代码随之执行。

第三重:运行时 OIDC Token 内存提取

GitHub Actions 的 OIDC 信任publisher机制允许从特定环境自动发布 npm 包。攻击者不是去偷 token,而是在运行时从 Actions runner 进程的内存中直接提取 OIDC token,从而以 TanStack 的合法身份发布恶意包。

整个过程不需要修改 TanStack 官方的发布 workflow——攻击者只是利用了发布流程本身的运行时行为。


恶意代码行为

安装受影响版本时,恶意 router_init.js(约2.3MB混淆代码)会执行以下操作:

1. 云凭据窃取

目标 路径/接口
AWS IMDS 元数据服务 + Secrets Manager
GCP 元数据服务
Kubernetes Service Account Token
HashiCorp Vault Token 文件
SSH 私钥 ~/.ssh/ 目录
GitHub Token 环境变量、gh CLI 配置、.git-credentials
npm Token ~/.npmrc

2. 数据外传

窃取的数据通过 Session/Oxen 信使文件上传网络 传输到以下地址:

filev2.getsession.org
seed1.getsession.org
seed2.getsession.org
seed3.getsession.org

传输使用端到端加密,无攻击者控制的 C2 服务器,按 IP 或域名封禁是唯一的网络层防御手段

3. 横向传播

恶意代码还会:

  1. 枚举受害者在 npm 上维护的包
  2. 用相同的恶意代码重新发布这些包
  3. 形成自我传播的供应链污染

受影响包列表(部分)

包名 受影响版本 修复版本
@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/solid-router 1.169.5 – 1.169.8 1.169.9
@tanstack/vue-router 1.169.5 – 1.169.8 1.169.9
@tanstack/react-start 1.167.68 – 1.167.71 1.167.72
@tanstack/solid-start 1.167.65 – 1.167.68 1.167.69
@tanstack/router-generator 1.166.45 – 1.166.48 1.166.49

所有42个受影响包的列表见 GitHub Advisory:https://github.com/advisories/GHSA-g7cv-rxg3-hmpx


如何检测是否中招

1. 检查已安装的包版本

# 检查是否安装了受影响版本
npm ls @tanstack/react-router
npm ls @tanstack/router-core
# ... 其他包

# 查看完整依赖树
npm ls --all | grep "@tanstack"

2. 检查 package-lock.json

恶意版本的 package-lock.json 中包含以下特征:

"optionalDependencies": {
  "@tanstack/setup": "github:tanstack/setup"
}

如果看到这个条目,说明中招了。

3. 检查凭据访问时间

如果在 2026-05-11 19:20-19:26 UTC 之间执行过 npm installpnpm installyarn install,且安装了受影响版本,必须立即轮换所有凭据


应急响应

立即行动

  1. 停止使用受影响版本

    # 升级所有 @tanstack/* 包
    npm update "@tanstack/*"
    
  2. 轮换所有凭据

    • AWS/GCP 云凭据
    • GitHub Token(个人 Access Token、C.I. Token)
    • npm Token
    • SSH 私钥
  3. 检查云审计日志 查看5月11日-12日期间是否有异常云 API 调用

  4. 撤销并重新生成所有访问密钥

网络层防御

由于 C2 使用了 Session/Oxen 网络,无法通过传统域名封禁阻断:

# 防火墙规则示例(Linux)
iptables -A OUTPUT -d getsession.org -j REJECT
iptables -A OUTPUT -d filev2.getsession.org -j REJECT

检测工具

# GitHub 上有现成的检测脚本
git clone https://github.com/Caixa-git/tanstack-shield
cd tanstack-shield
npm install
npm run scan

防御建议

对开发者

  1. 不要盲目 npm install — 使用 npm ci 或锁定版本
  2. 检查包版本的发布时间 — 5月11日前后突然发布的大版本要警惕
  3. 使用 package-lock.json — 确保依赖版本固定
  4. 审查 GitHub Actions 权限 — 最小权限原则
  5. 不要在 Actions 中直接执行来自 PR 的代码

对企业

  1. npm audit — 定期扫描依赖漏洞
  2. 私有 npm 镜像 — 预审核后才放行
  3. 网络隔离 — CI 环境无法访问外部未知服务
  4. 凭据轮换策略 — 定期自动轮换,不依赖人工

思维延伸

这次攻击最值得思考的一点:攻击者没有偷任何人的密码,也没有拿下任何服务器

他们只是利用了 GitHub Actions 生态中三个已知漏洞类的组合:

  1. pull_request_target 的错误信任
  2. fork/base 之间的缓存边界
  3. OIDC token 运行时内存可提取

这意味着即使用最小的权限、最干净的环境,只要用了有漏洞的 Actions 配置,就可能成为受害者。

供应链安全不只是"保护好我的 token",更是"理解我依赖的每一个工具链的信任模型"。


参考

  • GitHub Advisory:https://github.com/advisories/GHSA-g7cv-rxg3-hmpx
  • TanStack 官方:https://tanstack.com/
  • 检测工具:https://github.com/Caixa-git/tanstack-shield
  • The Hacker News 报道:https://thehackernews.com