Mini Shai-Hulud 供应链攻击事件解析与检测指南

2026 年 5 月 11 日,出现了一起针对 npm 与 PyPI 生态的协同供应链攻击。此次攻击同时波及多个知名的 npm 与 PyPI 软件包。

这不是一次普通的恶意包投放事件。攻击者并未简单依赖窃取 npm 凭据,而是利用 GitHub Actions、缓存污染、OIDC Token 滥用、恶意依赖、持久化守护进程以及多通道 C2 基础设施,构建了一条完整的供应链入侵链路。

TanStack 相关恶意版本发布具体时间:北京时间 5 月 12 日凌晨 3:20 至 3:26(UTC+8)


一、事件概览

本次攻击影响了 npm 与 PyPI 两大生态中的多个高价值包。

主要受影响的软件包:

  • @tanstack 下的软件包,例如 @tanstack/react-router,这是 React 生态中最广泛使用的路由库之一,每周下载量约 1200 万次, @tanstack/vue-router 也受到影响。
  • @uipath 下的软件包,包括 UiPath 企业自动化平台相关工具、CLI 与 Agent SDK
  • @mistralai/mistralai,即 Mistral AI 官方 TypeScript 客户端
  • @opensearch-project/opensearch
  • PyPI 上的 mistralai: 2.4.6
  • PyPI 上的 guardrails-ai : 0.10.1

npm 团队已经注意到该攻击活动,并快速移除了恶意版本。

可以在文章结尾查看已知的具体受影响的软件包。

二、TanStack 攻击链:GitHub Actions 成为突破口

TanStack 的失陷源于一条针对 GitHub Actions 的复杂漏洞利用链(包含三个漏洞):

攻击链大致如下:

  1. 攻击者 fork 了 TanStack/router 仓库。
  2. 攻击者将 fork 后的仓库重命名为 zblgg/configuration 规避了 Fork 列表的审查。
  3. 攻击者提交 Pull Request,触发目标仓库中的 pull_request_target 工作流。
  4. 该工作流错误地 checkout 并执行了攻击者 fork 中的代码。
  5. 攻击者借此污染 GitHub Actions 缓存,将恶意 pnpm store 写入缓存。
  6. 后续合法维护者的 PR 被合并到 main 分支时,release workflow 恢复了被污染的缓存。
  7. 攻击者控制的二进制文件从 GitHub Actions Runner 的进程内存中读取 OIDC Token。
  8. 攻击者使用这些 Token 发布恶意 npm 包版本。

这一链路最值得关注的地方在于:攻击者无需窃取 npm 凭据,也能完成恶意包发布。

这说明在现代软件供应链中,包管理账号本身已不再是唯一的关键资产。CI/CD 工作流、缓存、OIDC Token、发布权限和工作流边界同样是高价值攻击面。

UiPath 的感染变种

@tanstack 受到攻击后不久,@uipath 也宣告失陷。这些包使用一个预安装脚本(node setup.mjs)下载 Bun 运行时环境并执行恶意 payload。这与之前 SAP 失陷事件中的交付机制相同。UiPath 变种使用了重新混淆过的 payload 和不同的 Campaign Key,但连接的是相同的 C2(命令与控制)基础设施。

三、恶意 Payload:凭证窃取与蠕虫式传播

本次恶意 payload 具备自我传播能力,主要窃取以下类型的凭据和身份材料:

它主要锁定以下目标:

  • CI/CD 令牌(GitHub Actions OIDC、GitLab、CircleCI)
  • 云服务凭证(AWS IMDSv2、GCP、Azure)
  • Kubernetes 服务账号
  • HashiCorp Vault
  • Package registry tokens

蠕虫行为:恶意软件会使用窃取来的 npm 令牌和 GitHub Actions OIDC 令牌,进一步向受害者拥有写入权限的其他包发布投毒版本,从而在 npm 生态系统中像蠕虫一样迅速蔓延。

破坏性的本地守护进程

如果恶意软件发现了有效的目标 ghp_ 开头的 GitHub Personal Access Tokengho_ 开头的 OAuth Token,它在本地会安装一个持久化守护进程:

macOS:

1
~/Library/LaunchAgents/com.user.gh-token-monitor.plist

Linux:

1
~/.config/systemd/user/gh-token-monitor.service

如果它因 GitHub 令牌被撤销而收到 40X 错误,该进程会尝试执行 rm -rf ~/,直接清空用户主目录! 不过该守护进程会在运行 24 小时后自动退出。

注:与之前的 Mini Shai-Hulud 变种一样,该恶意软件会检查系统是否配置为俄语,如果是,则直接终止运行,不窃取任何数据。

四、检查指南

  1. 排查软件包:搜索 lockfiles 和 CI 日志,是否出现受影响的软件包版本。检查包根目录下是否存在 router_init.jssetup.mjs
  2. 检查并清除持久化威胁:在开发者机器上搜索 gh-token-monitor 守护进程并将其删除(路径见下方指标)。
  3. 轮换所有凭证:如果怀疑受到影响,请立即轮换 GitHub 令牌、npm 令牌、AWS 凭证、Vault 令牌、Kubernetes 服务账号和 CI/CD 机密信息。

    警告:在吊销 GitHub 令牌之前,请务必先检查并移除持久化守护进程,以免触发恶意软件的(rm -rf ~/)命令。

  4. 检查 IDE 目录:检查 .claude/.vscode/ 目录中是否残留 router_runtime.jssetup.mjs。这些文件在执行 npm uninstall 后仍可能驻留。
  5. 屏蔽 C2 目标域名:在 DNS/代理层面拦截 git-tanstack.com 以及 *.getsession.org

文件

文件名称 详情 SHA-256 / SHA-1
router_init.js 2,341,681 bytes SHA256:
``ab4fcadaec49c03278063dd269ea5eef82d24f2124a8e15d7b90f2fa8601266c`
router_init.js 2,339,346 bytes SHA256:
2ec78d556d696e208927cc503d48e4b5eb56b31abc2870c2ed2e98d6be27fc96
SHA1:
e7d582b98ca80690883175470e96f703ef6dc497
setup.mjs 5,047 bytes SHA256:
2258284d65f63829bd67eaba01ef6f1ada2f593f9bbe41678b2df360bd90d3df
SHA1:
12f35b1081b17d21815b35feb57ab03d02482116
opensearch_init.js - SHA1:
820fa07a7328b6cf2b417078e103721d4d8f2e79

网络 IOC

类型 目标
C2 域名 git-tanstack.com
Session 种子节点 seed1.getsession.org, seed2.getsession.org, seed3.getsession.org
Session 文件服务器 filev2.getsession.org
C2 IP 地址 83.142.209.194
PyPI Payload URL git-tanstack.com/tmp/transformers.pyz

其他特征

类别 特征描述
服务名称 gh-token-monitor
macOS 路径 ~/Library/LaunchAgents/com.user.gh-token-monitor.plist
Linux 路径 ~/.config/systemd/user/gh-token-monitor.service
运行时痕迹 router_runtime.js , tanstack_runner.js
Hook 执行命令 preinstall: node setup.mjs
恶意 Git 依赖 github:tanstack/router#79ac49eedf774dd4b0cfa308722bc463cfe5885c
特定运行环境 Bun Version 1.3.13

五、受影响的软件包

PyPI

NPM

Package Affected Versions
@beproduct/nestjs-auth 0.1.2, 0.1.3, 0.1.4, 0.1.5, 0.1.6, 0.1.7, 0.1.8, 0.1.9, 0.1.10, 0.1.11, 0.1.12, 0.1.13, 0.1.14, 0.1.15, 0.1.16, 0.1.17, 0.1.18, 0.1.19
@cap-js/db-service 2.10.1
@cap-js/postgres 2.2.2
@cap-js/sqlite 2.2.2
@dirigible-ai/sdk 0.6.2, 0.6.3
@draftauth/client 0.2.1, 0.2.2
@draftauth/core 0.13.1, 0.13.2
@draftlab/auth 0.24.1, 0.24.2
@draftlab/auth-router 0.5.1, 0.5.2
@draftlab/db 0.16.1, 0.16.2
@mesadev/rest 0.28.3
@mesadev/saguaro 0.4.22
@mesadev/sdk 0.28.3
@mistralai/mistralai 2.2.2, 2.2.3, 2.2.4
@mistralai/mistralai-azure 1.7.1, 1.7.2, 1.7.3
@mistralai/mistralai-gcp 1.7.1, 1.7.2, 1.7.3
@ml-toolkit-ts/preprocessing 1.0.2, 1.0.3
@ml-toolkit-ts/xgboost 1.0.3, 1.0.4
@opensearch-project/opensearch 3.5.3, 3.6.2, 3.7.0, 3.8.0
@squawk/airport-data 0.7.4, 0.7.5, 0.7.6, 0.7.7, 0.7.8
@squawk/airports 0.6.2, 0.6.3, 0.6.4, 0.6.5, 0.6.6
@squawk/airspace 0.8.1, 0.8.2, 0.8.3, 0.8.4, 0.8.5
@squawk/airspace-data 0.5.3, 0.5.4, 0.5.5, 0.5.6, 0.5.7
@squawk/airway-data 0.5.4, 0.5.5, 0.5.6, 0.5.7, 0.5.8
@squawk/airways 0.4.2, 0.4.3, 0.4.4, 0.4.5, 0.4.6
@squawk/fix-data 0.6.4, 0.6.5, 0.6.6, 0.6.7, 0.6.8
@squawk/fixes 0.3.2, 0.3.3, 0.3.4, 0.3.5, 0.3.6
@squawk/flight-math 0.5.4, 0.5.5, 0.5.6, 0.5.7, 0.5.8
@squawk/flightplan 0.5.2, 0.5.3, 0.5.4, 0.5.5, 0.5.6
@squawk/geo 0.4.4, 0.4.5, 0.4.6, 0.4.7, 0.4.8
@squawk/icao-registry 0.5.2, 0.5.3, 0.5.4, 0.5.5, 0.5.6
@squawk/icao-registry-data 0.8.4, 0.8.5, 0.8.6, 0.8.7, 0.8.8
@squawk/mcp 0.9.1, 0.9.2, 0.9.3, 0.9.4, 0.9.5
@squawk/navaid-data 0.6.4, 0.6.5, 0.6.6, 0.6.7, 0.6.8
@squawk/navaids 0.4.2, 0.4.3, 0.4.4, 0.4.5, 0.4.6
@squawk/notams 0.3.6, 0.3.7, 0.3.8, 0.3.9, 0.3.10
@squawk/procedure-data 0.7.3, 0.7.4, 0.7.5, 0.7.6, 0.7.7
@squawk/procedures 0.5.2, 0.5.3, 0.5.4, 0.5.5, 0.5.6
@squawk/types 0.8.1, 0.8.2, 0.8.3, 0.8.4, 0.8.5
@squawk/units 0.4.3, 0.4.4, 0.4.5, 0.4.6, 0.4.7
@squawk/weather 0.5.6, 0.5.7, 0.5.8, 0.5.9, 0.5.10
@supersurkhet/cli 0.0.2, 0.0.3, 0.0.4, 0.0.5, 0.0.6, 0.0.7
@supersurkhet/sdk 0.0.2, 0.0.3, 0.0.4, 0.0.5, 0.0.6, 0.0.7
@tallyui/components 1.0.1, 1.0.2, 1.0.3
@tallyui/connector-medusa 1.0.1, 1.0.2, 1.0.3
@tallyui/connector-shopify 1.0.1, 1.0.2, 1.0.3
@tallyui/connector-vendure 1.0.1, 1.0.2, 1.0.3
@tallyui/connector-woocommerce 1.0.1, 1.0.2, 1.0.3
@tallyui/core 0.2.1, 0.2.2, 0.2.3
@tallyui/database 1.0.1, 1.0.2, 1.0.3
@tallyui/pos 0.1.1, 0.1.2, 0.1.3
@tallyui/storage-sqlite 0.2.1, 0.2.2, 0.2.3
@tallyui/theme 0.2.1, 0.2.2, 0.2.3
@tanstack/arktype-adapter 1.166.12, 1.166.15
@tanstack/eslint-plugin-router 1.161.9, 1.161.12
@tanstack/eslint-plugin-start 0.0.4, 0.0.7
@tanstack/history 1.161.9, 1.161.12
@tanstack/nitro-v2-vite-plugin 1.154.12, 1.154.15
@tanstack/react-router 1.169.5, 1.169.8
@tanstack/react-router-devtools 1.166.16, 1.166.19
@tanstack/react-router-ssr-query 1.166.15, 1.166.18
@tanstack/react-start 1.167.68, 1.167.71
@tanstack/react-start-client 1.166.51, 1.166.54
@tanstack/react-start-rsc 0.0.47, 0.0.50
@tanstack/react-start-server 1.166.55, 1.166.58
@tanstack/router-cli 1.166.46, 1.166.49
@tanstack/router-core 1.169.5, 1.169.8
@tanstack/router-devtools 1.166.16, 1.166.19
@tanstack/router-devtools-core 1.167.6, 1.167.9
@tanstack/router-generator 1.166.45, 1.166.48
@tanstack/router-plugin 1.167.38, 1.167.41
@tanstack/router-ssr-query-core 1.168.3, 1.168.6
@tanstack/router-utils 1.161.11, 1.161.14
@tanstack/router-vite-plugin 1.166.53, 1.166.56
@tanstack/solid-router 1.169.5, 1.169.8
@tanstack/solid-router-devtools 1.166.16, 1.166.19
@tanstack/solid-router-ssr-query 1.166.15, 1.166.18
@tanstack/solid-start 1.167.65, 1.167.68
@tanstack/solid-start-client 1.166.50, 1.166.53
@tanstack/solid-start-server 1.166.54, 1.166.57
@tanstack/start-client-core 1.168.5, 1.168.8
@tanstack/start-fn-stubs 1.161.9, 1.161.12
@tanstack/start-plugin-core 1.169.23, 1.169.26
@tanstack/start-server-core 1.167.33, 1.167.36
@tanstack/start-static-server-functions 1.166.44, 1.166.47
@tanstack/start-storage-context 1.166.38, 1.166.41
@tanstack/valibot-adapter 1.166.12, 1.166.15
@tanstack/virtual-file-routes 1.161.10, 1.161.13
@tanstack/vue-router 1.169.5, 1.169.8
@tanstack/vue-router-devtools 1.166.16, 1.166.19
@tanstack/vue-router-ssr-query 1.166.15, 1.166.18
@tanstack/vue-start 1.167.61, 1.167.64
@tanstack/vue-start-client 1.166.46, 1.166.49
@tanstack/vue-start-server 1.166.50, 1.166.53
@tanstack/zod-adapter 1.166.12, 1.166.15
@taskflow-corp/cli 0.1.24, 0.1.25, 0.1.26, 0.1.27, 0.1.28, 0.1.29
@tolka/cli 1.0.2, 1.0.3, 1.0.4, 1.0.5, 1.0.6
@uipath/access-policy-sdk 0.3.1
@uipath/access-policy-tool 0.3.1
@uipath/admin-tool 0.1.1
@uipath/agent-sdk 1.0.2
@uipath/agent-tool 1.0.1
@uipath/agent.sdk 0.0.18
@uipath/aops-policy-tool 0.3.1
@uipath/ap-chat 1.5.7
@uipath/api-workflow-tool 1.0.1
@uipath/apollo-core 5.9.2
@uipath/apollo-react 4.24.5
@uipath/apollo-wind 2.16.2
@uipath/auth 1.0.1
@uipath/case-tool 1.0.1
@uipath/cli 1.0.1
@uipath/codedagent-tool 1.0.1
@uipath/codedagents-tool 0.1.12
@uipath/codedapp-tool 1.0.1
@uipath/common 1.0.1
@uipath/context-grounding-tool 0.1.1
@uipath/data-fabric-tool 1.0.2
@uipath/docsai-tool 1.0.1
@uipath/filesystem 1.0.1
@uipath/flow-tool 1.0.2
@uipath/functions-tool 1.0.1
@uipath/gov-tool 0.3.1
@uipath/identity-tool 0.1.1
@uipath/insights-sdk 1.0.1
@uipath/insights-tool 1.0.1
@uipath/integrationservice-sdk 1.0.2
@uipath/integrationservice-tool 1.0.2
@uipath/llmgw-tool 1.0.1
@uipath/maestro-sdk 1.0.1
@uipath/maestro-tool 1.0.1
@uipath/orchestrator-tool 1.0.1
@uipath/packager-tool-apiworkflow 0.0.19
@uipath/packager-tool-bpmn 0.0.9
@uipath/packager-tool-case 0.0.9
@uipath/packager-tool-connector 0.0.19
@uipath/packager-tool-flow 0.0.19
@uipath/packager-tool-functions 0.1.1
@uipath/packager-tool-webapp 1.0.6
@uipath/packager-tool-workflowcompiler 0.0.16
@uipath/packager-tool-workflowcompiler-browser 0.0.34
@uipath/platform-tool 1.0.1
@uipath/project-packager 1.1.16
@uipath/resource-tool 1.0.1
@uipath/resourcecatalog-tool 0.1.1
@uipath/resources-tool 0.1.11
@uipath/robot 1.3.4
@uipath/rpa-legacy-tool 1.0.1
@uipath/rpa-tool 0.9.5
@uipath/solution-packager 0.0.35
@uipath/solution-tool 1.0.1
@uipath/solutionpackager-sdk 1.0.11
@uipath/solutionpackager-tool-core 0.0.34
@uipath/tasks-tool 1.0.1
@uipath/telemetry 0.0.7
@uipath/test-manager-tool 1.0.2
@uipath/tool-workflowcompiler 0.0.12
@uipath/traces-tool 1.0.1
@uipath/ui-widgets-multi-file-upload 1.0.1
@uipath/uipath-python-bridge 1.0.1
@uipath/vertical-solutions-tool 1.0.1
@uipath/vss 0.1.6
@uipath/widget.sdk 1.2.3
agentwork-cli 0.1.4, 0.1.5
cmux-agent-mcp 0.1.3, 0.1.4, 0.1.5, 0.1.6, 0.1.7, 0.1.8
cross-stitch 1.1.3, 1.1.4, 1.1.5, 1.1.6, 1.1.7
git-branch-selector 1.3.3, 1.3.4, 1.3.5, 1.3.6, 1.3.7
git-git-git 1.0.8, 1.0.9, 1.0.10, 1.0.11, 1.0.12
guardrails-ai 0.10.1
intercom-client 7.0.4
lightning 2.6.2, 2.6.3
mbt 1.2.48
mistralai 2.4.6
ml-toolkit-ts 1.0.4, 1.0.5
nextmove-mcp 0.1.3, 0.1.4, 0.1.5, 0.1.6, 0.1.7
safe-action 0.8.3, 0.8.4
ts-dna 3.0.1, 3.0.2, 3.0.3, 3.0.4, 3.0.5
wot-api 0.8.1, 0.8.2, 0.8.3, 0.8.4

结语

这次攻击展示了供应链攻击的新趋势:攻击者不再只盯着包管理器账号,而是将 GitHub Actions、缓存、OIDC、开发者终端、CI/CD Secret 和开源包发布流程串联成完整攻击链。

对于安全团队而言,单纯“升级依赖”已经不够。真正有效的防护需要覆盖从代码提交、CI 执行、凭据签发、包发布到开发者本地环境的全链路。

这次事件也再次提醒我们:CI/CD 是生产系统的一部分,依赖包是执行代码的一部分,开发者机器也是供应链边界的一部分。

参考资料