Mini Shai-Hulud Worm Targets TanStack npm Ecosystem via Chained CI/CD Exploitation (CVE-2026-45321)
May 19th, 2026
Critical

Our Cyber Threat Intelligence Unit is tracking active exploitation of CVE-2026-45321, which targets the TanStack router npm package ecosystem through the Mini Shai-Hulud worm. On May 11, 2026, between 19:20 and 19:26 UTC, threat actors published 84 malicious versions across 42 @tanstack/* packages by chaining three known vulnerabilities: a pull_request_target "Pwn Request" misconfiguration, GitHub Actions cache poisoning across the fork-to-base trust boundary, and runtime OIDC token extraction from runner process memory. These packages were authenticated using TanStack's legitimate release pipeline identity and included valid SLSA Build Level 3 provenance attestations, making them indistinguishable from legitimate releases using standard supply chain controls. This incident is the fourth wave of the Shai-Hulud campaign and represents the first documented npm supply chain worm to produce valid SLSA provenance for malicious packages. By the end of the day, the worm had self-propagated to at least 170 npm packages, with confirmed secondary victims including Mistral AI, UiPath, and Squawk. Organizations that installed affected @tanstack/* packages on May 11, 2026, should consider the install host potentially compromised, with risks including credential exposure, unauthorized code execution, and significant impact on software delivery pipelines.
Technical Details
Threat Type: Software Supply Chain Compromise / CI/CD Workflow Abuse
Severity: Critical
CVE: CVE-2026-45321
CVSS Score: 9.6 Critical (CNA: GitHub, Inc.)
Affected Component: TanStack router family npm packages
Affected Scope: At least 170 npm packages, including secondary victims Mistral AI, UiPath, and Squawk
Threat Actors: TeamPCP (also tracked as DeadCatx3, PCPcat, ShellForce, CipherForce) (attributed by StepSecurity)
Attack Chain:
Malicious Fork and Identity Spoofing: The attacker forked TanStack/router under the account zblgg, renaming it zblgg/configuration to avoid appearing in fork-list searches.
A malicious commit (65bf499d) was authored under the spoofed identity claude <[email protected]> with a [skip ci] tag to suppress automated CI checks.
Pwn Request via pull_request_target: PR #7378 ("WIP: simplify history build") triggered a vulnerable pull_request_target workflow, executing attacker-controlled fork code inside the base repository's CI environment.
GitHub Actions Cache Poisoning: The vite_setup.mjs payload poisoned the pnpm package cache under the precomputed key:
Linux-pnpm-store-6f9233a50def742c09fde54f56553d6b449a535adf87d4083690539f49ae4da11
The poisoned cache persisted until the legitimate release.yml workflow restored it.
OIDC Token Extraction: Attacker-controlled binaries located the Runner.Worker process via /proc/*/cmdline, then read /proc/<pid>/maps and /proc/<pid>/mem to dump runner memory and extract the OIDC token.
Unauthorized Package Publishing: The extracted token authenticated directly to registry.npmjs.org, publishing malicious packages under TanStack's legitimate trusted publisher identity with valid SLSA Build Level 3 provenance attestations.
Payload Execution: The malicious router_init.js was delivered via a prepare lifecycle script, executing on npm install, pnpm install, and yarn install.
Credential Harvesting: The malware targeted GitHub Actions tokens, npm credentials, AWS/GCP credentials, Kubernetes service-account tokens, HashiCorp Vault tokens, SSH private keys, CI/CD secrets, and Claude Code session history files at ~/.claude/projects/*.jsonl.
Exfiltration: Data was exfiltrated through the Session/Oxen P2P network (filev2[.]getsession[.]org, seed1-3[.]getsession[.]org) and via GitHub GraphQL API dead-drop commits using dependabout/... branch naming patterns.
Workflow Injection: A malicious .github/workflows/codeql_analysis.yml was injected into accessible repositories to harvest GitHub Actions secrets on future workflow runs.
Self-Propagation: Using stolen OIDC identities and npm maintainer relationships, the worm republished trojanized packages across the ecosystem, reaching at least 170 confirmed packages.
Persistence and Dead-Man's Switch:
Persistent artifacts were written to .claude/, .vscode/, and platform-specific monitoring services.
A dead-man's switch polled stolen GitHub tokens and executed rm -rf ~/ upon detecting revocation.
Payload Behavior:
The router_init.js payload (~2.3 MB, obfuscated and AES-256-GCM encrypted) executes via prepare lifecycle hook. Key behaviors include:
Credential harvesting across GitHub, npm, AWS/GCP, Kubernetes, HashiCorp Vault, SSH, and CI/CD secret stores
Collection of Claude Code session history (~/.claude/projects/*.jsonl)
Encrypted exfiltration via Session/Oxen P2P and GitHub GraphQL API dead drops
.github/workflows/codeql_analysis.yml injection for ongoing secret harvesting
Worm-style republishing of trojanized packages via stolen maintainer credentials
Persistent backdoor components surviving package removal and reboots
Dead-man's switch executing rm -rf ~/ on token revocation

Impact
Exposure of sensitive credentials, including GitHub tokens, npm credentials, cloud provider secrets, Kubernetes service-account tokens, SSH keys, HashiCorp Vault tokens, and CI/CD environment variables
Persistent backdoor deployment across developer workstations, build servers, and CI/CD environments, allowing prolonged unauthorized access and potential lateral movement
Data exfiltration through the Session/Oxen P2P network and GitHub GraphQL API, potentially bypassing traditional network security controls
Worm-style self-propagation leading to compromise of additional npm packages and downstream applications across the software supply chain
Risk of destructive data loss through the dead-man's switch mechanism, which executes rm -rf ~/ if stolen GitHub tokens are revoked before persistence removal
Abuse of valid SLSA Build Level 3 provenance attestations, reducing the reliability of provenance-based trust validation
Potential operational disruption due to incident response, credential rotation, forensic investigation, and package remediation efforts
Possible regulatory and compliance exposure if sensitive or customer-related information was accessed or exfiltrated
Detection Method
Monitor GitHub Actions Workflow Activity:
Review GitHub audit logs and workflow execution logs for suspicious usage of the pull_request_target event, particularly workflows that check out forked repository code, write to GitHub Actions cache, or request OIDC tokens (id-token: write)
Investigate unexpected cache restore and write operations and unauthorized workflow modifications
Monitor for anomalous branch naming patterns resembling Dependabot updates (dependabout/.../setup-formatter — note the misspelling "dependabout," not "dependabot") or commits authored by [email protected]
Audit repositories for the unexpected presence of .github/workflows/codeql_analysis.yml if it was not intentionally added by your team
Inspect Endpoint and Sysmon Logs for Persistence Activity:
Monitor EDR/Sysmon logs for creation of suspicious persistence files and hidden runtime artifacts, including:
.claude/setup.mjs
.claude/router_runtime.js
.vscode/setup.mjs
gh-token-monitor.sh
Relevant Windows Sysmon Event IDs: Event ID 1 (Process Creation), Event ID 11 (File Creation), Event ID 13 (Registry Modification)
Investigate execution of unusual node, npm, pnpm, or npx child processes spawned by developer tools or CI/CD runners
Monitor Network and DNS Activity:
Configure DNS, proxy, firewall, and EDR telemetry to detect outbound communication to known campaign infrastructure (see Indicators of Compromise)
Monitor for traffic to the Session/Oxen P2P network; IP-level blocking is insufficient given the distributed node architecture, and DNS-level blocking of *.getsession.org is the practical perimeter control
Monitor for unexpected outbound requests to GitHub's GraphQL API (api.github.com/graphql) originating from CI/CD runners or developer workstations outside of normal workflow operations, as the worm uses this channel for credential dead-drop exfiltration
Inspect Installed Packages for Compromise Indicators:
Scan installed @tanstack/* packages for the presence of router_init.js in the package root or the malicious optionalDependencies entry "@tanstack/setup": "github:tanstack/router#79ac49ee..." in package.json
Indicators of Compromise
Type | Indicator | Description |
SHA-256 | ab4fcadaec49c03278063dd269ea5eef82d24f2124a8e15d7b90f2fa8601266c | router_init.js — malicious payload present in compromised @tanstack/* package tarballs |
SHA-256 | 2ec78d556d696e208927cc503d48e4b5eb56b31abc2870c2ed2e98d6be27fc96 | tanstack_runner.js — secondary malicious payload |
Domain | filev2[.]getsession[.]org | Primary exfiltration endpoint via Session/Oxen P2P network |
Domain | api[.]masscan[.]cloud | Campaign C2 infrastructure |
Domain | git-tanstack[.]com | Campaign C2 infrastructure |
Domain | litter[.]catbox[.]moe | Second-stage payload hosting |
Domain | seed1[.]getsession[.]org | Session/Oxen P2P network node |
Domain | seed2[.]getsession[.]org | Session/Oxen P2P network node |
Domain | seed3[.]getsession[.]org | Session/Oxen P2P network node |
URL | litter[.]catbox[.]moe/h8nc9u[.]js | Second-stage payload |
URL | litter[.]catbox[.]moe/7rrc6l[.]mjs | Second-stage payload |

Recommendations
Disable the dead-man's switch before revoking any credentials:
Revoking tokens while the monitor service is active will trigger rm -rf ~/, causing irreversible home directory destruction.
On Linux, stop and remove ~/.config/systemd/user/gh-token-monitor.service and ~/.local/bin/gh-token-monitor.sh.
On macOS, unload and remove ~/Library/LaunchAgents/com.user.gh-token-monitor.plist.
Rotate all exposed credentials (npm tokens, GitHub PATs, AWS/GCP credentials, Vault tokens, Kubernetes service-account tokens, and SSH private keys) only after persistence is fully removed.
Remove compromised @tanstack/* package versions from all environments.
Use npm install --ignore-scripts when inspecting packages to prevent lifecycle script execution.
Note that Bun does not execute lifecycle scripts by default, limiting install-time payload delivery; this does not eliminate the need to inspect and remediate affected versions.
Remove persistence artifacts from .claude/ and .vscode/ directories, including router_runtime.js, setup.mjs, and any injected .github/workflows/codeql_analysis.yml files not intentionally added by your team.
Audit pull_request_target workflows for fork code execution and cache write access; separate these operations or replace with pull_request (read-only fork context).
Scope id-token: write permissions to only the specific publishing job that requires them and pin all GitHub Actions references to commit SHAs.
Purge GitHub Actions caches for any repository with vulnerable pull_request_target workflows.
Block *.getsession.org, api.masscan.cloud, git-tanstack.com, and litter.catbox.moe at the DNS level.
Monitor GitHub audit logs, CI/CD pipelines, and npm publish events for anomalous OIDC token usage, unauthorized workflow changes, and unexpected package publishes.
Deploy dependency scanning to identify compromised package versions across environments.
Conclusion
The Mini Shai-Hulud worm’s exploitation of CVE-2026-45321 sets a new standard for npm supply chain threats. By leveraging legitimate CI/CD infrastructure instead of stealing credentials, the attacker created malicious packages that were indistinguishable from legitimate ones, even with provenance attestation. Organizations should coordinate an immediate response across security, DevOps, and cloud teams. Remove persistence before revoking credentials to prevent irreversible data loss. In the long term, this incident demonstrates that while SLSA provenance attestations are necessary, they are not sufficient. They must be combined with behavioral analysis during installation and more secure CI/CD configurations.