Date Observed: May 11, 2026
Ecosystem: npm, PyPI
Targets: Developers using @tanstack/react-router and related packages; UiPath, Mistral AI, OpenSearch, and Guardrails AI users
Attack Type: GitHub Actions cache poisoning, OIDC token extraction from runner memory, npm worm self-propagation
Impact: 84 malicious package versions across 42 @tanstack/* npm packages; PyPI packages also compromised; credentials stolen from GitHub, AWS, GCP, Kubernetes, and HashiCorp Vault environments
Key Takeaways
- TeamPCP used a chain of three GitHub Actions weaknesses to publish 84 malicious @tanstack/* package versions, without ever stealing an npm credential.
- @tanstack/react-router has roughly 12 million weekly downloads. Any developer or CI system that installed an affected version on May 11, 2026, should treat that machine as compromised.
- The malware spreads on its own: once it runs, it finds every other package the affected maintainer publishes and infects those too.
- Removing the package with npm uninstall does not clean up the infection. The malware hides in VS Code and Claude Code configuration files and re-runs on every IDE open.
- The malicious packages carried valid provenance from TanStack’s real release pipeline, so provenance checks alone did not catch the compromise.
On May 11, 2026, attackers published 84 malicious versions across 42 @tanstack/* npm packages in about six minutes. Packages like @tanstack/react-router are used by millions of developers every week. No long-lived npm credential was stolen to start the attack; instead, the attackers manipulated TanStack’s release pipeline and extracted a short-lived OIDC token from runner memory.
Within hours, the attack spread further. Packages from UiPath, Mistral AI, OpenSearch, and the Python package guardrails-ai were also hit. This is TeamPCP’s new known campaign using the same malware family, called “Mini Shai-Hulud.” It is tracked under GitHub Security Advisory GHSA-g7cv-rxg3-hmpx.
Scope and Impact of the Attack
Packages hit: 42 @tanstack/* packages (84 malicious versions), plus packages from @uipath, @mistralai, @opensearch-project, and other namespaces.
Python packages hit: guardrails-ai@0.10.1 and mistralai@2.4.6 on PyPI.
Download volume: @tanstack/react-router alone gets around 12 million installs per week. The @uipath and @opensearch-project packages are widely used across enterprise teams.
What gets stolen: GitHub tokens, npm tokens, AWS access keys (pulled directly from cloud metadata), Google Cloud credentials, Azure secrets, Kubernetes service tokens, HashiCorp Vault tokens, SSH keys, and over 100 types of credential files, including crypto wallet files and AI tool configs stored on the developer’s machine.
If an affected package ran on a build server or a developer machine, treat every secret on that system as stolen.
How the TanStack Attack Worked
Stage 0: Setting the Trap
The attacker created a copy (fork) of TanStack’s GitHub repository and renamed it to look unrelated, so it would not show up in normal fork lists. They added a hidden malicious script file into the fork and opened a pull request.
Stage 1: Poisoning the Build Cache
TanStack had a workflow file that, when a pull request arrived, would download and build the code from the PR, even from an untrusted fork. The attacker’s script ran during that process and replaced part of TanStack’s build cache with a version the attacker controlled.
The cache is like a saved snapshot of the build environment, used to speed up future builds. Once the attacker wrote their bad version into it, the poison was stored, waiting for TanStack’s own release process to use it. The attacker then quietly closed the pull request and the cache stayed in place.
Stage 2: Stealing the Publish Token from Memory
The next time a TanStack maintainer merged a normal, legitimate code change to the main branch, the release workflow started. It restored the build cache, but now it was loading the attacker’s poisoned version.
The malicious files inside that cache searched through the memory of the running build process and extracted a temporary security token (called an OIDC token) that the build server uses to publish packages to npm. This token lives only in memory; it is never written to disk, but the attacker’s code found and copied it anyway.
Stage 3: Publishing Fake Packages Through the Real Pipeline
With that stolen token, the attackers published 84 malicious versions to npm during two closely timed release runs. Because the token came from TanStack’s own trusted pipeline, the packages looked fully legitimate. They even passed npm’s package signing checks.
How the Attack Works
When a developer installs one of the infected packages, a hidden script inside router_init.js runs automatically in the background. It does two things simultaneously:
- Steals credentials: it scans the system for cloud access keys, GitHub tokens, database passwords, SSH keys, and anything else it can find.
- Spreads itself: it checks what other packages the same developer or build system publishes, then releases infected versions of those packages too. One install becomes many.
Credentials leave the system through three separate routes, making it hard to block just one:
- A fake domain set up by the attackers (git-tanstack[.]com)
- Session, a decentralized messaging network that is not commonly blocked by firewalls
- GitHub’s own API, which is commonly allowlisted and was used as a trusted exfiltration channel
Persistence on the machine: The script drops files into VS Code’s settings folder and Claude Code’s settings folder. The malware writes persistence hooks into IDE configuration files, so it can re-run when the IDE opens, even after the package is removed.
Why This Matters to DevOps and DevSecOps Teams
This attack worked because it used trusted systems against themselves. The publish token was never stored in a file; it was taken from memory during a legitimate build run. OIDC publishing (the secure approach TanStack was already using) did not prevent the attack. It only changed which token the attacker targeted.
The malicious packages carried valid provenance from TanStack’s real release pipeline, meaning they passed the automated checks designed to confirm where a package came from. Those checks passed because the attacker used TanStack’s real pipeline. Provenance tells you a package came from a specific workflow; it does not tell you whether that workflow was compromised.
Running npm uninstall is not enough. The malware writes itself into IDE configuration files before npm finishes installing. Those files run the payload again on every future IDE session until manually removed.
The malware also includes retaliatory behavior tied to stolen GitHub tokens. Public reporting indicates it monitors whether a stolen token has been revoked, and if it detects that change, it attempts to trigger a destructive cleanup command on the affected host. For that reason, teams should isolate the machine and remove the persistence mechanism before revoking suspicious GitHub tokens.
How InvisiRisk Protects Against This Attack
Build Proxy / Network Interception
InvisiRisk’s BAF sits inside the CI/CD build environment and watches every outbound connection. When the malware inside an infected package attempts to send stolen credentials to attacker-controlled infrastructure, the InvisiRisk BAF can intercept and block those outbound connections before data leaves the runner. This blocks the exfiltration routes simultaneously, at the moment the payload runs, not after.
Stability Buffer Period
InvisiRisk’s BAF blocks any package published in the last 48 hours (the window is configurable) before allowing it into a build. All 84 malicious @tanstack versions were identified as malicious within 20 minutes of being published. Under a 48-hour stability window, these newly published versions would have been held before entering a protected pipeline, stopping the attack before the payload ever ran.
Unauthorized API Action Enforcement
InvisiRisk’s BAF enforces rules on what API calls a build is allowed to make. The malware creates GitHub repositories and publishes npm packages using stolen tokens during the build, both actions that a legitimate build should never perform. BAF blocks unauthorized POST and PUT calls to GitHub’s API and npm’s registry, stopping both the data exfiltration through dead-drop repositories and the worm from spreading to new packages.
Why Build-Time Defenses Matter
This Mini Shai-Hulud wave makes one thing clear: the CI/CD pipeline is the attack surface. The attacker did not need to steal a password or compromise a developer’s machine to start. A misconfigured GitHub Actions workflow and a fork was enough. Defenses built only around registry scanning, package signing, or post-install detection have no visibility at the moment this attack executes. Enforcement that runs inside the build, intercepting traffic, blocking unauthorized API actions, and applying a cooldown to newly published packages, is what stops this class of attack.


