Skip to content

Cybersecurity · Supply Chain Security

Two npm Supply Chain Attacks in Six Weeks: What TanStack and React Native Aria Teach Every Developer

In May and June 2026, two separate supply chain attacks hit the npm ecosystem — TanStack (42 packages) and React Native Aria (17 packages). They used different entry points, had different payloads, and should change how every team handles third-party dependencies.

Abhishek Gupta

Abhishek Gupta

8 min read

Two npm Supply Chain Attacks in Six Weeks: What TanStack and React Native Aria Teach Every Developer

Sponsored

Share

On May 11, 2026, an attacker published 84 malicious versions across 42 TanStack npm packages in a six-minute window. Then, 26 days later, on June 6, a separate attacker compromised 17 React Native Aria and GlueStack packages. The two attacks look similar on the surface (npm packages, malware, millions of downloads) but they work completely differently, exploit different weaknesses, and require different defences.

Understanding both isn’t optional anymore. The npm ecosystem has become a reliable attack surface, and the playbooks are getting more sophisticated.

Attack comparison: packages compromised and weekly downloads at risk

The TanStack attack: when your CI/CD pipeline becomes the entry point

The threat group known as TeamPCP, which previously operated a similar worm called “Shai-Hulud,” returned in May 2026 with an updated variant. This time, the target was the TanStack ecosystem, a set of packages with tens of millions of weekly downloads used across React, Solid, Vue, and Angular projects.

The attack ran from 19:20 to 19:26 UTC on May 11. In those six minutes, the attacker published 84 malicious versions across 42 @tanstack/* packages. An external researcher detected the compromise publicly 20 to 26 minutes after the first malicious publish. The malicious versions were removed shortly after.

The method combined three techniques:

Step 1: The Pwn Request pattern. GitHub’s pull_request_target event was designed to let workflows access secrets for external PRs. But it runs in the context of the base repository (which has access to secrets, OIDC tokens, and protected branches). If a workflow doesn’t properly isolate fork PRs, an attacker who opens a PR from a fork can trigger code execution inside the base repository’s context.

Step 2: CI/CD cache poisoning. The attacker poisoned the GitHub Actions cache across the fork/base boundary. This let them inject content that would be used when the base repository’s workflow ran, including during legitimate operations.

Step 3: OIDC token extraction. GitHub Actions provides short-lived OIDC tokens that prove the workflow is running from an expected repository and branch. The npm registry (and increasingly other registries) can accept these tokens for authentication instead of a persistent API key. The attacker extracted the OIDC token from the running Actions runner process and used it to authenticate as the TanStack publish identity.

The resulting malware ran via a binding.gyp node-gyp hook, meaning it executed at npm install time, not at runtime. The payload harvested GitHub Actions secrets, cloud provider credentials, and package registry tokens. It also tried to persist in AI coding assistant configuration files (Cursor, Copilot, Windsurf config directories) to gain a foothold in developer machines.

The attack is the first documented case of a malicious npm package carrying valid SLSA provenance. SLSA attestations are supposed to let you verify that a package actually came from the expected CI/CD pipeline. Here, the attacker was inside the CI/CD pipeline, so the attestation was technically valid.

The React Native Aria attack: account compromise, obfuscated RAT

The React Native Aria compromise (June 6, 2026, 4:33 PM EST) was a different operation. Instead of exploiting a CI/CD pipeline, the attacker obtained a public npm access token that belonged to an authorized maintainer of the GlueStack/react-native-aria packages.

With that token, they published modified versions of 17 packages:

  • All 16 @react-native-aria/* packages (focus, utils, overlays, interactions, toggle, switch, checkbox, radio, button, menu, listbox, tabs, combobox, disclosure, slider, separator)
  • @gluestack-ui/utils

The malicious code was hidden using whitespace-based obfuscation, pushing the payload far off-screen to the right, past typical terminal width and IDE wrapping. A casual diff review would show the file changed but the malicious content would be invisible without scrolling horizontally.

The payload was a remote access trojan (RAT). However, the maintainers noted a key mitigating factor: react-native-aria is a frontend-only library. It runs no install-time scripts, no postinstall hooks, and no node-gyp bindings. The malicious code lived in the library files themselves. It would only execute it would only execute if those files were imported and run in a context where the RAT payload could reach a network endpoint. For most React Native frontends, that’s an unusable execution path.

The response was quick: malicious versions deprecated, compromised tokens revoked, 2FA enabled for publishing and GitHub access.

What makes these attacks different

The two incidents look similar on first read, but they exploit different failure modes:

TanStack (Mini Shai-Hulud)React Native Aria
Entry pointGitHub Actions CI/CD exploitStolen maintainer token
Attack vectorOIDC token extraction from runnerCompromised npm access token
Payload deliverynode-gyp install hook (runs at npm install)Embedded in library files (runs at import)
Self-propagatingYes (harvested and reused credentials)No
SLSA provenanceValid (bypassed by being inside CI)Not present
Practical execution riskHigh (install-time on developer machines)Low (frontend-only, no install hook)
Detection time26 minutesHours (discovered by Aikido Security)

The TanStack attack is more dangerous from a credential-harvesting perspective. It ran on every developer machine that ran npm install during the 26-minute window, with full access to environment variables. The React Native Aria attack had a lower practical impact but was harder to detect because the malicious code had to be found inside library source files.

The SLSA provenance problem

The TanStack attack deserves a separate note on SLSA. Supply chain security frameworks increasingly rely on provenance attestations as a layer of defence. The idea: if a package’s build attestation proves it was built and signed by the expected CI pipeline, then consumers can verify they’re running code that was genuinely produced by the project.

The Mini Shai-Hulud attack breaks this assumption. By compromising the CI/CD system itself, the attacker produced packages with valid SLSA provenance, because the package really did come from the TanStack CI/CD pipeline. It’s just that the pipeline was also running the attacker’s code.

Provenance is still worth implementing. It raises the bar significantly for most attacks, which typically involve impersonation from outside the pipeline. But treating it as a guarantee is wrong. You still need to protect the pipeline itself.

Five things to do after reading this

The two incidents together point to a short, practical checklist. The DevSecOps and SBOMs post covers the broader pipeline hardening picture, but for supply chain specifically:

1. Enable 2FA for npm publishing. Both attacks involved stolen credentials (OIDC token, API token). Requiring 2FA for npm publishes would not have stopped the TanStack OIDC attack, but it is the baseline for the account-compromise vector.

2. Pin exact versions in your lockfile. A lockfile that records exact versions and integrity hashes (package-lock.json, pnpm-lock.yaml) means a newly published malicious version of a package doesn’t automatically become what you install. Your lockfile would still reference the prior clean version until someone explicitly runs npm update.

3. Restrict pull_request_target in GitHub Actions. If you have workflows that use pull_request_target and run on pull requests from forks, they are the primary attack surface for Pwn Request attacks. GitHub’s documentation has a guide to safely handling this. The short version: don’t pass fork PR code into a workflow that has access to secrets, and don’t mix fork PR triggers with secret access.

4. Add automated supply chain scanning. Tools like Socket.dev, Snyk, and GitHub’s Dependabot can flag newly published versions that show unusual patterns: new install scripts, large file size changes, and obfuscated code. Neither attack would have been blocked by these tools alone, but they help catch things faster than a 26-minute detection window.

5. Treat install-time scripts as a security boundary. The TanStack payload ran via node-gyp. Many packages have postinstall or preinstall scripts that execute automatically on npm install. If you’re in a high-security environment, consider npm install --ignore-scripts and only running install scripts from packages you’ve explicitly verified. Tools like socket CLI can audit install scripts before you run them.

The npm ecosystem is not going to stop being a target. The packages with tens of millions of weekly downloads are worth compromising, and the attack techniques are well-documented. The question is whether your project’s dependency hygiene is up to the threat.


The Node.js security release that patched 12 CVEs in June (covered in the Node.js security release post) is a different attack surface (runtime vulnerabilities vs. supply chain), but both serve as a reminder that the JavaScript ecosystem’s security posture requires active maintenance, not set-and-forget.

Frequently asked questions

How did the TanStack npm supply chain attack work?
On May 11, 2026, the threat group TeamPCP exploited a 'Pwn Request' pattern in GitHub Actions — combining pull_request_target vulnerabilities with cache poisoning across the fork/base trust boundary. The attacker extracted a short-lived OIDC token from the Actions runner process and used it to publish 84 malicious versions across 42 @tanstack/* packages. The malware ran a payload via a node-gyp install hook that harvested GitHub Actions secrets, cloud provider keys, and package registry tokens, then tried to persist in AI coding assistant configs.
How is the React Native Aria attack different from TanStack?
The React Native Aria attack (June 6, 2026) was a direct account compromise, not a CI/CD exploit. Attackers obtained a valid public access token from an authorized maintainer, then published malicious versions of 17 @react-native-aria and gluestack-ui packages. The malware used whitespace-based obfuscation — pushing malicious code off-screen in the file — to hide the payload. Because the library is frontend-only and runs no install scripts, the practical execution risk was limited, but the compromise was real.
Was anyone affected by these attacks?
The TanStack attack ran for only 20-26 minutes before external researcher @ashishkurmi (StepSecurity) detected it publicly. The malicious versions were unpublished quickly. For React Native Aria, the maintainers downplayed impact because the libraries run no install-time code and no post-install scripts. No confirmed data breaches were attributed to either attack, but both underline that even short exposure windows matter when credentials are involved.
What is the significance of the TanStack attack carrying valid SLSA provenance?
SLSA (Supply chain Levels for Software Artifacts) provenance is meant to let consumers verify that a published package actually came from the expected CI/CD pipeline. The TanStack attack is the first documented case of an attacker obtaining a legitimate OIDC token from within the CI/CD system itself and using it to publish malicious packages with valid SLSA attestations. This means provenance alone is insufficient — it proves the package came from a pipeline, not that the pipeline wasn't compromised.
What should developers do right now to protect their projects?
Five steps: (1) Enable 2FA on npm publishing accounts — both attacks were enabled by compromised or stolen credentials. (2) Pin dependencies with exact versions in your lockfile and commit the lockfile. (3) Restrict pull_request_target workflows — they are the most common GitHub Actions attack surface. (4) Add automated supply chain scanning (Socket.dev, Snyk, Dependabot) to catch malicious versions before they reach production. (5) Treat install-time scripts (postinstall, node-gyp hooks) as a security boundary.

Sources

Sponsored

Sponsored

Discussion

Join the conversation.

Comments are powered by GitHub Discussions. Sign in with your GitHub account to leave a comment.

Sponsored