On May 11, 2026, between 19:20 and 19:26 UTC, an attacker published 84 malicious versions across 42 @tanstack/* npm packages, triggering one of the most significant software supply chain incidents in recent memory. The npm supply chain compromise exploited a chain of three distinct vulnerabilities to bypass security controls and inject malware into widely-used open-source libraries.
An external researcher working for StepSecurity detected the attack approximately 20 minutes after the malicious publish and immediately notified both TanStack and npm security. The malicious versions were deprecated within hours, and npm security was engaged to pull tarballs from the registry server-side.
How the Attack Unfolded
The attack combined three separate vulnerabilities. First, the bundle-size.yml workflow used the pull_request_target trigger, which runs pull request code from untrusted forks while maintaining access to the base repository’s secrets and cache. Second, GitHub Actions cache entries were poisoned across the trust boundary between a fork and the main repository. Third, attacker-controlled binaries extracted an OIDC token directly from the GitHub Actions runner process memory, allowing unauthorized npm publishes.
On May 10, an attacker created a fork of TanStack/router named github.com/zblgg/configuration and authored a malicious commit containing a ~30,000-line bundled JavaScript payload. A pull request titled “WIP: simplify history build” was opened on May 11 at 10:49 UTC. Because the pull_request_target trigger bypasses first-time-contributor approval requirements, automated workflows immediately executed the fork’s code.
The benchmark-pr job checked out the malicious pull request code and ran pnpm install, which triggered the execution of vite_setup.mjs. This payload was specifically designed to poison the pnpm cache with a key that the legitimate release.yml workflow would later restore. When the poisoned cache was restored during the next push to main, attacker-controlled binaries executed during the build phase.
Malware Capabilities and Impact
When developers or CI environments ran npm install, pnpm install, or yarn install against any affected version, the malicious optionalDependencies entry resolved and executed a ~2.3 MB obfuscated router_init.js file. The script harvested credentials from AWS IMDS, AWS Secrets Manager, GCP metadata, Kubernetes service-account tokens, Vault tokens, ~/.npmrc files, GitHub tokens, and SSH private keys.
Stolen credentials were exfiltrated over the Session/Oxen messenger file-upload network using end-to-end encryption, with no attacker-controlled command-and-control server. The malware also self-propagated by enumerating other packages the victim maintained via the npm registry search API and republishing them with the same injection.
The 42 affected packages impacted the following families: @tanstack/history, @tanstack/react-query, @tanstack/angular-query, @tanstack/svelte-query, @tanstack/solid-query, @tanstack/vue-query, @tanstack/react-table, @tanstack/angular-table, @tanstack/svelte-table, @tanstack/solid-table, @tanstack/vue-table, @tanstack/react-form, @tanstack/angular-form, @tanstack/svelte-form, @tanstack/solid-form, @tanstack/vue-form, @tanstack/react-virtual, @tanstack/angular-virtual, @tanstack/svelte-virtual, @tanstack/solid-virtual, @tanstack/vue-virtual, @tanstack/router, @tanstack/react-router, @tanstack/angular-router, @tanstack/svelte-router, @tanstack/solid-router, and @tanstack/vue-router.
Root Cause and Vulnerability Chain
The attack required all three vulnerabilities working in concert. The pull_request_target pattern allowed fork code to execute in the base repository’s trust context. GitHub Actions cache poisoning allowed a pull request running in the base repository’s cache scope to inject malicious data that production workflows on main would later restore.
Notably, the cache entry written by actions/cache@v5 is not gated by workflow permissions. Cache writes use a runner-internal token, not the workflow GITHUB_TOKEN, meaning setting permissions: contents: read does not block cache mutation. The OIDC token extraction technique was not novel; it utilized the same memory-dumping approach documented in the March 2025 tj-actions/changed-files compromise.
The malware location the GitHub Actions Runner.Worker process via /proc/*/cmdline, read /proc/
Detection and Response Timeline
Detection occurred externally and rapidly. At approximately 19:50 UTC on May 11, a researcher with StepSecurity opened GitHub issue #7383 with complete technical analysis of the malicious optionalDependencies fingerprint and an initial list of 14 affected packages. Within minutes, the researcher notified npm security directly.
TanStack maintainers acknowledged the incident around 20:00 UTC and began coordinated incident response. At 20:10 UTC, all team push permissions were removed from GitHub in case maintainer machines were compromised. By 20:30 UTC, the maintainers had compiled the full indicators of compromise and requested npm security pull all affected tarballs from the registry.
A comprehensive scan of all 295 @tanstack/* packages by 21:00 UTC confirmed the scope: 42 packages with 84 malicious versions. All cache entries for all TanStack repositories were purged via GitHub’s API. A hardening pull request was merged the same day, restructuring bundle-size.yml, adding repository_owner guards, and pinning third-party action references to specific commit SHAs.
Credential Rotation and Future Mitigation
TanStack strongly recommends that anyone who installed an affected version on May 11, 2026 rotate AWS, GCP, Kubernetes, Vault, GitHub, npm, and SSH credentials reachable from the install host. No npm tokens were stolen, and the npm publish workflow itself was not directly compromised, but treat the install host as potentially compromised.
The incident exposed gaps in current practices. No internal alerting mechanisms detected the malicious publishes; the team learned of the compromise entirely from a third party. Additionally, floating action references (@v6.0.2, @main) on third-party actions create standing supply chain security risk independent of this incident. The incident also highlighted limitations in npm policy: the “no unpublish if dependents exist” rule prevented immediate unpublishing of affected versions, creating hours of delay during which malicious tarballs remained installable.
OIDC trusted-publisher binding, while generally secure, offers no per-publish review mechanism. Once configured, any code path in a workflow can mint a publish-capable token. TanStack is evaluating moving to short-lived classic tokens with manual review or implementing provenance-source-verification to detect publishes from unexpected workflow steps.
Unconfirmed Clean Families
The following @tanstack/* package families were confirmed to not contain malicious versions: @tanstack/query*, @tanstack/table*, @tanstack/form*, @tanstack/virtual*, @tanstack/store, and @tanstack/start (the meta-package, not @tanstack/start-*).
For the full list of affected versions and mitigation guidance, refer to GitHub Security Advisory GHSA-g7cv-rxg3-hmpx and the tracking issue at TanStack/router#7383. The incident underscores the critical importance of auditing pull_request_target workflows, pinning external action dependencies to commit hashes, implementing cache-access controls, and establishing internal alerting for unexpected publishes.
Source: tanstack.com





