🎯 CVE-2026-45321 深度技术分析:漏洞根因 · PoC/EXP · 检测指纹

🎯 CVE 全聚合深度分析

CVE-2026-45321 深度技术分析

📊 聚合 4 来源🧪 含 PoC
NVD-LatestCISA-KEVGitHub-AdvisoryPoC-in-GitHub

摘要:CVE-2026-45321 是一起针对 npm 生态的高危供应链攻击事件,CVSS 评分为 9.6,影响 TanStack 旗下 42 个 @tanstack/* 包。攻击者于 2026 年 5 月 11 日约 19:20–19:26 UTC 期间,利用 GitHub Actions 的多个配置弱点,在未修改官方发布工作流的情况下,通过与 TanStack/router 绑定的合法 OIDC trusted-publisher 身份向 npm 发布了 84 个恶意版本(每个包 2 个)。恶意包在安装时执行约 2.3MB 混淆脚本 router_init.js,可窃取云元数据服务、密钥管理服务、Kubernetes、Vault、npm 及 GitHub 令牌等敏感凭据。该漏洞已被 CISA 列入 KEV 目录,属于需紧急关注的利用中漏洞。

📌 漏洞概述

CVE 编号:CVE-2026-45321
GitHub Advisory:GHSA-g7cv-rxg3-hmpx
CVSS 评分:9.6(Critical)
受影响产品:npm 上的 @tanstack/* 系列包,共 42 个包,每个包均发布两个恶意版本(发布时段为 2026-05-11 19:20–19:26 UTC)
漏洞类型:供应链攻击 / 不安全的 GitHub Actions 配置组合利用(pull_request_target 误用、Actions 缓存投毒、OIDC token 内存泄露)

攻击者并未修改 TanStack/router 仓库的发布工作流文件,也没有盗取任何长期凭据。相反,攻击者利用 GitHub Actions 中三个已知的信任边界弱点,在合法的 OIDC 发布身份下,向 npm 推送了携带恶意安装脚本的“可信”版本。CISA KEV 在公布后即将该漏洞列入已知被利用漏洞目录,显示出其在野利用的严重性与紧迫性。

🔬 漏洞根因分析

本次攻击并非单一漏洞,而是三个已知漏洞类别的组合利用,最终绕过 GitHub Actions 的 trusted-publisher 安全模型。深入分析如下:

  • pull_request_target “Pwn Request” 误配置:
    GitHub Actions 的 pull_request_target 事件允许从 fork 的 PR 在目标仓库的上下文中运行,因此可以访问仓库 secrets 和 OIDC token。标准的最佳实践是:在 pull_request_target 工作流中不得直接 checkout 未受信任的 PR 代码,更不能执行其中的脚本。TanStack 仓库很可能存在一个可由外部贡献者触发的 pull_request_target 工作流,该工作流虽然自身未被修改,但其中的某个步骤会处理 PR 的输入或注释信息,攻击者可能通过精心构造的 PR 内容将恶意 PowerShell/bash 命令注入到该工作流的上下文中。攻击者借此在目标仓库的 runner 上取得初始执行权,为后续攻击做准备。
  • GitHub Actions 缓存跨 fork↔base 信任边界投毒:
    pull_request_target 工作流中,缓存虽然对 fork PR 默认是只读的,但对目标仓库的默认分支或特定分支是可写的。攻击者利用第一步获得的执行权,将恶意代码写入该工作流使用的缓存中——例如 Node.js 依赖缓存(pnpm-storenpm-cache)或编译产物的 build cache。由于发布流程和 PR 流程可能共享相同的缓存键(如 deps- + hash 等),攻击者成功将恶意 payload“播种”到缓存中,而官方发布工作流在后续运行时无需修改任何源码文件即可从缓存中加载污染后的依赖或脚本。这种跨信任边界投毒绕过了通过修改仓库代码来攻击的检测手段,使得工作流文件本身始终是“干净”的。
  • 从 runner 进程运行时内存中提取 OIDC token:
    GitHub Actions 的 OIDC token 在 job 运行时通过环境变量 ACTIONS_ID_TOKEN_REQUEST_TOKENACTIONS_ID_TOKEN_REQUEST_URL 提供给步骤,而该 token 本身通常只存在于 Actions runner 的内部进程中,并不写入文件系统。攻击者通过缓存投毒,在发布工作流执行依赖安装或构建步骤时,运行了恶意代码(例如一个 preinstall 脚本)。该恶意代码在 runner 的同一个用户上下文中执行,能够读取环境变量,或通过读取 runner 进程的 /proc//dev/mem 映射、内存转储等方式提取 OIDC token 的请求令牌。之后恶意代码调用 OIDC 端点获取 id_token,该 token 的 sub 声明绑定到 TanStack/router 的 trusted-publisher 关系。攻击者用该 token 向 npm registry 认证,成功以官方身份发布恶意包。

这三个弱点相互依赖:pull_request_target 提供了初始的代码执行入口,缓存投毒负责将恶意 payload 跨工作流地传递到发布流程,而 OIDC token 的内存提取则是最后“借用”官方身份的跳板。整个链路无需攻击者拥有任何长期凭据,也无需修改发布工作流文件,因而避开了常规的 GitHub 审计与分支保护机制,也解释了为什么恶意版本在短时间内集中发布,且每个包仅两个版本——整个攻击窗口非常短,直到 19:26 后才被人工发现并暂停。

💥 影响与危害

攻击者将恶意包以“官方版本”的形式发布到 npm,意味着所有使用 @tanstack/* 依赖并执行重装/更新的开发者或 CI 系统,在安装过程中会直接执行携带的 payload。实际影响包括:

  • 信息窃取面极广:恶意 payload(router_init.js)会从以下位置收集凭据:AWS IMDS 实例元数据及其中的临时角色凭证、AWS Secrets Manager;GCP 元数据服务;Kubernetes service-account token;HashiCorp Vault token;~/.npmrc 中的 npm token;以及 GitHub token。这些凭据一旦被窃取,攻击者可以进一步横向移动至云环境、私有代码仓库、内部系统。
  • 供应链传播放大:由于 TanStack 是极其流行的 React/Vue 生态库(例如 TanStack Query、TanStack Router),任一中间包被开发者引用后,攻击者不仅窃取了终端开发者的机器,还可能利用拿到的 GitHub token 对依赖该包的其它项目发起二次攻击。事实上,后续披露的信息显示该恶意包已进一步扩散至 @mistralai@opensearch-project@draftlabsafe-action 等 20 多个下游包,形成“Mini Shai-Hulud”蠕虫式传播效应。
  • 对开放源代码信任体系的冲击:攻击者利用合法 OIDC trusted-publisher 身份发布恶意版本,意味着 npm 的“可信发布者”验证机制被绕过。用户校验包完整性后仍可能安装恶意代码,这从根本上动摇了以 npm 为信任根的安全假设。开发者在事件后必须假设所有相关包版本均可能被替换,所有被污染版本上的安装记录应视为潜在入侵指标。

CISA 将 CVE-2026-45321 列入 KEV,说明该漏洞已被用于实际攻击,并且它专门针对云基础设施和开发工具链,可能造成多租户环境的连锁失陷。任何在攻击窗口期间执行过 npm install 的机器都应被视为已被入侵并立即进行取证分析。

🛡️ 修复与缓解

截至 NVD 最新发布信息,厂商未提供独立的“补丁版本”来修复本次漏洞,因为恶意版本不是代码缺陷,而是发布流程之外的供应链污染。修复的核心是清除恶意版本并恢复可信交付链,具体缓解措施如下:

  • 立即规避所有恶意版本:检查 package-lock.jsonpnpm-lock.yamlyarn.lockbun.lock,确认是否包含 2026-05-11 19:20–19:26 UTC 期间发布的 @tanstack/* 版本。若受影响,将所有包回滚至该时间点之前的最后一个稳定版本,并将恶意版本号加入 deny 名单。
  • 扫描并清除持久化后门:参考 PoC 工具(tanstack-compromise-checker)中的 IOC,检查项目与用户目录中是否存在 router_init.jstanstack_runner.js、Claude Code SessionStart hooks、VS Code folderOpen tasks、gh-token-monitor(LaunchAgent/systemd)、恶意 GitHub workflow 以及 @tanstack/setup optionalDependency 等持久化痕迹。
  • 轮换所有可能泄露的凭据:如果在受影响时间窗内安装过这些包,必须立刻轮换 AWS IAM 临时/长期密钥、GCP 服务账号密钥、Kubernetes ServiceAccount token、Vault token、npm ~/.npmrc 中的 token,以及 GitHub Personal Access Token、OAuth App token 和 SSH 密钥。同时审查云环境中的 IAM 策略,确认没有攻击者通过泄露的临时令牌创建了新的持久访问入口。
  • 加固 GitHub Actions 供应链配置:
    • 避免在 pull_request_target 工作中直接 checkout 或执行 PR 中的代码;若必须使用,请先进行代码审查,并确保 checkout 的是受信分支而非 PR 合并提交。
    • 将缓存键与不可信 PR 上下文完全隔离,或改用 Key-based caching 并限制写入权限。对发布流程单独使用不共享的缓存实例,缓存命中后应进行完整性校验。
    • 对 OIDC token 的获取增加权限限制:在发布权限中进行 id-token: write 最小化声明,并配置 audience/issuer 校验,确保 token 只能用于预期的 npm 发布方。
    • 启用 GitHub 的强制 code review 和 branch protection,并使用 StepSecurity 等工具审计 Actions 工作流,防止“Pwn Request”和 cache poisoning 模式。
  • 监控后续扩散:由于攻击者可能已通过窃取的 token 对更多包发起持续投毒,建议定期订阅 GitHub Advisory,使用 npm audit 以及 Snyk/StepSecurity 的报告,关注“Mini Shai-Hulud”变种。

对于无法立即升级或确认完成凭证轮换的团队,建议暂时停止使用 @tanstack/* 相关依赖,并隔离安装有受影响包的开发环境,直至完成彻底的镜像重建和事件响应调查。该漏洞是供应链攻击中“信任链被旁路”的典型警示:不仅要在代码层审查漏洞,还要对 CI/CD 管道中的每一个信任边界(事件触发、缓存、 OIDC)做深度防御。

🧪 PoC 复现

从 GitHub 公开仓库抓取的实际 PoC 代码(仓库)。

📋 代码元数据语言md来源ry-allan/tanstack-compromise-checker针对性✅ 已验证与漏洞相关(代码含 CVE 引用)依赖见代码注释/README用法详见代码注释中的使用说明

# tanstack-compromise-checker

>**⚠️ Disclaimer:** This tool was built for my own use case. All indicators are derived from the following advisory sources:
>- [GHSA-g7cv-rxg3-hmpx](https://github.com/advisories/GHSA-g7cv-rxg3-hmpx)
>- [Snyk: TanStack npm packages compromised](https://snyk.io/blog/tanstack-npm-packages-compromised/)
>
- [StepSecurity: Mini Shai-Hulud deep dive](https://www.stepsecurity.io/blog/mini-shai-hulud-is-back-a-self-spreading-supply-chain-attack-hits-the-npm-ecosystem)
>>If new IOCs,payload variants,or attacker infrastructure emerge after this was last updated,
they won't be detected. Always cross-check against the latest published advisories.

Detects the TanStack supply chain compromise ([CVE-2026-45321](https://github.com/advisories/GHSA-g7cv-rxg3-hmpx)) and related Mini Shai-Hulud worm artifacts in a local project checkout.

The script is intended for fast triage in source checkouts,CI jobs,
and Docker builds. A clean result means none of the known indicators below were found. It is not a full forensic investigation or a guarantee that a machine was never exposed.

## What it checks

|Category |Details ||---|---||**Compromised packages** |All 42 `@tanstack/*` packages + 20 worm-propagated secondary victims (`@mistralai`,`@opensearch-project`,`@draftlab`,`safe-action`,etc.) ||
**Lockfile scan** |`pnpm-lock.yaml`,`yarn.lock`,`bun.lock`,`bun.lockb`,`package-lock.json`,including multiline npm v3 `packages` entries and Yarn v1 selector/version stanzas ||**Payload files** |`router_init.js`,`tanstack_runner.js` in `node_modules` with SHA-256 verification;exact hash matches and hash mismatches both fail the scan ||**Infection vector** |
`@tanstack/setup` as `optionalDependency` in any installed package ||**Persistence** |Claude Code `SessionStart` hooks in both project and home settings,VS Code `folderOpen` tasks,`gh-token-monitor` (LaunchAgent + systemd),malicious GitHub workflows ||**Disk artifacts** |`.claude/router_runtime.js`,`.claude/setup.mjs`,`.vscode/setup.mjs`,`gh-token-monitor.sh`,`com.user.gh-token-monitor.plist` ||
**Source IOCs** |Attacker commit hashes,C2 domains (`api.masscan.cloud`,`git-tanstack.com`),Session Protocol endpoints,PBKDF2 salt,campaign strings ||**Git history** |Commits authored by `claude@users.noreply.github.com` ||**Branch patterns** |`dependabot/github_actions/format/*` and `dependabout/*/setup-formatter` ||**AI tool configs** |Tampered `.claude/mcp.json` and `.kiro/settings/mcp.json` ||
**Running processes** |Daemonized payload and `gh-token-monitor` processes ||**npm tokens** |Ransom-marked tokens (`IfYouRevokeThisTokenItWillWipeTheComputerOfTheOwner`) |## What it does not cover

- It checks known package names,versions,filenames,hashes,domains,branch names,
and persistence paths from the public advisories. New attacker infrastructure or renamed payloads may require new indicators.
- It selects one project lockfile in package-manager priority order (`pnpm`,`yarn`,`bun`,then `npm`). If a repository intentionally carries multiple lockfiles,scan each relevant package-manager state separately.
- It can identify suspicious files and configuration,
but it does not remove malware,rotate secrets,revoke tokens,or image the host.
- The npm token check only runs when `npm` is available and authenticated enough for `npm token list`.
- Home-directory persistence checks inspect the current `HOME` of the process running the script. In CI or containers,
that may differ from a developer workstation home directory.

## Quick start

```bash
# Scan current directory
bash check-tanstack-compromise.sh .

# Scan a specific project
bash check-tanstack-compromise.sh /path/to/project

# One-liner (curl)
curl -sL https://raw.githubusercontent.com/ry-allan/tanstack-compromise-checker/main/check-tanstack-compromise.sh |
bash
```

Exit code `0` = no covered indicators found.
Exit code `1` = covered compromise or suspicious payload indicator found.

### Sample output (clean project)

```
═══════════════════════════════════════════════════════════════
  TanStack Supply Chain Compromise Check (CVE-2026-45321)
═══════════════════════════════════════════════════════════════
  Advisory: GHSA-g7cv-rxg3-hmpx
  Reference: https://snyk.io/blog/tanstack-npm-packages-compromised/
  Deep dive: https://www.stepsecurity.io/blog/mini-shai-hulud-is-back-…

[*] Scanning: /Users/xxxxx/repos/xxxxx

[*] Package manager: pnpm (pnpm-lock.yaml)

[*] Checking installed TanStack packages against 42 known-compromised versions…

[*] Checking worm-propagated secondary victims (Mini Shai-Hulud)…
[*]   Packages: @mistralai,
@opensearch-project,@draftlab,@draftauth,[*]   @dirigible-ai,safe-action,cmux-agent-mcp,nextmove-mcp,[*]   git-git-git,git-branch-selector,agentwork-cli,ml-toolkit-ts,[*]   wot-api,cross-stitch,ts-dna

[*] Scanning lockfile for known-compromised versions (pnpm-lock.yaml)…
[✓] No compromised versions in lockfile

[*] Checking for persistence artifacts (payload files,hooks,services,
C2)…
[✓] No malicious author commits in git history

───────────────────────────────────────────────────────────────
[✓] No compromise detected.
```

## Preventing future attacks

Install [Aikido Safe Chain](https://github.com/AikidoSec/safe-chain) to automatically scan every package install for malware:

```bash
curl -fsSL https://github.com/AikidoSec/safe-chain/releases/latest/download/install-safe-chain.sh |
sh
```

Restart your terminal afterwards. Safe Chain wraps `npm`,`npx`,`yarn`,`pnpm`,`pip`,`uv`,
and more — blocking packages younger than 48 hours and known-bad versions before they touch disk. No tokens or configuration required.

## Test coverage

The integration Dockerfile creates synthetic fixtures only. It does not download real compromised packages.

The main fixture asserts all 33 detection messages fire across package manifests,lockfiles,persistence artifacts,workflows,git history,
source IOCs,payload filenames,AI tool configs,
and remediation output:

```bash
docker build -f integration.Dockerfile -t tanstack-check-test .
```

The Docker build also includes targeted regression coverage for:

- `package-lock.json` v3 entries where the package name and compromised version appear on separate lines.
- Yarn v1 lockfile entries where the package selector and compromised `version` appear on separate lines.
- Hash-mismatched `router_init.js` payload filenames returning exit code `1`.
- Home-level Claude Code `SessionStart` hooks even when a clean project-level `.claude/settings.json` exists.

After building,
the image command can be run directly:

```bash
docker run --rm tanstack-check-test
```

## References

- [GHSA-g7cv-rxg3-hmpx](https://github.com/advisories/GHSA-g7cv-rxg3-hmpx)
- [Snyk: TanStack npm packages compromised](https://snyk.io/blog/tanstack-npm-packages-compromised/)
- [StepSecurity: Mini Shai-Hulud deep dive](https://www.stepsecurity.io/blog/mini-shai-hulud-is-back-a-self-spreading-supply-chain-attack-hits-the-npm-ecosystem)

⚔️ EXP 利用代码

截至分析时,Exploit-DB 未收录该 CVE 的公开利用代码。可利用上述 PoC 进行验证,或关注 Exploit-DB 更新。

🕵️ 检测指纹

当前规则库未收录针对该 CVE 的专用检测规则。建议:

  • 根据漏洞根因编写 Nuclei 检测模板
  • 在 WAF/IDS 中配置针对漏洞特征的规则
  • 关注漏洞指纹库更新

🤖 本文由漏洞情报系统自动聚合生成 · 2026-08-05 08:40 · 数据源: NVD/GitHub-Advisory/OSV/CISA-KEV/Exploit-DB/PoC-in-GitHub + 检测规则库

[!] CONTACT_CHANNELS

如需商务合作、技术咨询或漏洞反馈,请通过以下离岸节点联系作者。

> PING_AUTHOR (@A1RedTeam)