CVE-2026-45321 - TanStack npm supply-chain compromise

On 2026-05-11, 84 malicious versions across 42 @tanstack/* npm packages were published under a trusted TanStack identity. The advisory describes a chain that crossed three build boundaries: unsafe pull_request_target execution, GitHub Actions cache poisoning across fork and base repository trust zones, and extraction of an npm trusted-publishing OIDC token from the Actions runner process.

This is not a normal vulnerable dependency. Any developer workstation, CI runner, build image, cache, or artifact mirror that installed one of the exact malicious versions must be treated as potentially compromised because the payload harvested cloud credentials, GitHub tokens, npm tokens, SSH private keys, Kubernetes service-account tokens, Vault tokens, and other secrets available to the install process.

When to use it

Use this recipe when a repository, build image, CI workflow, package mirror, or developer environment may have installed a malicious @tanstack/* package version from the 2026-05-11 compromise. It is for exact-version compromise response, not generic dependency hygiene.

It is most valuable when the remediation must coordinate code changes, lockfile regeneration, cache and mirror quarantine, credential rotation, and GitHub Actions trust-boundary hardening in one reviewable packet.

Inputs

  • Package manifests, lockfiles, SBOMs, generated dependency reports, vendored modules, Docker layers, package-manager stores, and registry/proxy mirror metadata that may reference @tanstack/*.
  • CI and release workflow files, especially pull_request_target, cache restore/save behavior, npm trusted publishing, and jobs with id-token: write.
  • Build logs and runner/image inventory showing whether affected versions were installed on or after 2026-05-11 19:20 UTC, without exposing secrets.
  • Internal cache, mirror, and artifact-retention ownership for purging exact malicious package coordinates.
  • Credential-rotation ownership for GitHub, npm, cloud, SSH, Kubernetes, Vault, package-registry, and deployment credentials reachable by install scripts.

Affected versions

The affected set is exact-version based, not a broad semver range. Each package had two malicious versions, followed by a clean patched version.

Package Malicious versions First patched version
@tanstack/arktype-adapter 1.166.12, 1.166.15 1.166.16
@tanstack/eslint-plugin-router 1.161.9, 1.161.12 1.161.13
@tanstack/eslint-plugin-start 0.0.4, 0.0.7 0.0.8
@tanstack/history 1.161.9, 1.161.12 1.161.13
@tanstack/nitro-v2-vite-plugin 1.154.12, 1.154.15 1.154.16
@tanstack/react-router 1.169.5, 1.169.8 1.169.9
@tanstack/react-router-devtools 1.166.16, 1.166.19 1.166.20
@tanstack/react-router-ssr-query 1.166.15, 1.166.18 1.166.19
@tanstack/react-start 1.167.68, 1.167.71 1.167.72
@tanstack/react-start-client 1.166.51, 1.166.54 1.166.55
@tanstack/react-start-rsc 0.0.47, 0.0.50 0.0.51
@tanstack/react-start-server 1.166.55, 1.166.58 1.166.59
@tanstack/router-cli 1.166.46, 1.166.49 1.166.50
@tanstack/router-core 1.169.5, 1.169.8 1.169.9
@tanstack/router-devtools 1.166.16, 1.166.19 1.166.20
@tanstack/router-devtools-core 1.167.6, 1.167.9 1.167.10
@tanstack/router-generator 1.166.45, 1.166.48 1.166.49
@tanstack/router-plugin 1.167.38, 1.167.41 1.167.42
@tanstack/router-ssr-query-core 1.168.3, 1.168.6 1.168.7
@tanstack/router-utils 1.161.11, 1.161.14 1.161.15
@tanstack/router-vite-plugin 1.166.53, 1.166.56 1.166.57
@tanstack/solid-router 1.169.5, 1.169.8 1.169.9
@tanstack/solid-router-devtools 1.166.16, 1.166.19 1.166.20
@tanstack/solid-router-ssr-query 1.166.15, 1.166.18 1.166.19
@tanstack/solid-start 1.167.65, 1.167.68 1.167.69
@tanstack/solid-start-client 1.166.50, 1.166.53 1.166.54
@tanstack/solid-start-server 1.166.54, 1.166.57 1.166.58
@tanstack/start-client-core 1.168.5, 1.168.8 1.168.9
@tanstack/start-fn-stubs 1.161.9, 1.161.12 1.161.13
@tanstack/start-plugin-core 1.169.23, 1.169.26 1.169.27
@tanstack/start-server-core 1.167.33, 1.167.36 1.167.37
@tanstack/start-static-server-functions 1.166.44, 1.166.47 1.166.48
@tanstack/start-storage-context 1.166.38, 1.166.41 1.166.42
@tanstack/valibot-adapter 1.166.12, 1.166.15 1.166.16
@tanstack/virtual-file-routes 1.161.10, 1.161.13 1.161.14
@tanstack/vue-router 1.169.5, 1.169.8 1.169.9
@tanstack/vue-router-devtools 1.166.16, 1.166.19 1.166.20
@tanstack/vue-router-ssr-query 1.166.15, 1.166.18 1.166.19
@tanstack/vue-start 1.167.61, 1.167.64 1.167.65
@tanstack/vue-start-client 1.166.46, 1.166.49 1.166.50
@tanstack/vue-start-server 1.166.50, 1.166.53 1.166.54
@tanstack/zod-adapter 1.166.12, 1.166.15 1.166.16

Indicator-of-exposure

  • A manifest, lockfile, SBOM, build log, package cache, mirror, proxy registry, Docker layer, or generated dependency report includes one of the exact malicious @tanstack/* versions above.
  • CI or a developer machine ran npm install, npm ci, pnpm install, or yarn install for an affected dependency during or after the malicious publish window on 2026-05-11.
  • A package tarball contains the malicious indicators documented by TanStack: optionalDependencies["@tanstack/setup"] pointing to github:tanstack/router#79ac49eedf774dd4b0cfa308722bc463cfe5885c, a root-level router_init.js, or a helper named tanstack_runner.js.
  • GitHub Actions workflows use pull_request_target and then check out or execute fork-controlled code in the base repository trust context.
  • Release or publish workflows restore caches that can be written by untrusted PR workflows, especially when the release workflow has id-token: write, npm trusted publishing, package publishing tokens, cloud credentials, SSH keys, or deployment secrets.

Quick checks:

rg -n "@tanstack/|router_init\\.js|@tanstack/setup|79ac49eedf774dd4b0cfa308722bc463cfe5885c|pull_request_target|id-token: write|actions/cache|restore-keys" .
npm ls --all 2>/dev/null | rg "@tanstack/" || true
pnpm list --depth Infinity 2>/dev/null | rg "@tanstack/" || true
yarn list --pattern "@tanstack/" 2>/dev/null || true

Windows:

rg -n '@tanstack/|router_init\.js|@tanstack/setup|79ac49eedf774dd4b0cfa308722bc463cfe5885c|pull_request_target|id-token: write|actions/cache|restore-keys' .
npm ls --all 2>$null | rg '@tanstack/'
pnpm list --depth Infinity 2>$null | rg '@tanstack/'
yarn list --pattern '@tanstack/'

To inspect a tarball without executing lifecycle scripts:

npm pack @tanstack/react-router@1.169.8 --ignore-scripts
tar -xzf tanstack-react-router-*.tgz
grep -A5 '"optionalDependencies"' package/package.json
test ! -f package/router_init.js

Run tarball inspection only in a disposable directory. Do not run package install scripts for a suspected malicious version.

Remediation strategy

  • Remove every exact malicious version from manifests, lockfiles, vendored dependency folders, generated reports, Docker layers, package mirrors, and build caches. Upgrade to the first patched version or newer for each affected package.
  • Recreate lockfiles from a clean dependency graph. Do not trust a lockfile generated on a runner or workstation that may have executed the malicious package.
  • Delete node_modules, package-manager stores, CI workspaces, and build caches that may contain the affected tarballs. Pair the PR with the cache-quarantine workflow when the organization owns registry mirrors or pull-through caches.
  • Treat affected install environments as compromised. Rotate tokens and keys reachable by the install process, including GitHub tokens, npm tokens, cloud credentials, SSH keys, Kubernetes service-account tokens, Vault tokens, and package-registry credentials.
  • Audit GitHub Actions trust boundaries before re-enabling release automation: remove fork-controlled code execution from pull_request_target, isolate caches for untrusted PRs from release jobs, avoid broad restore-keys, and grant id-token: write only to the final publish job after the build inputs are fixed and verified.
  • Add package-version and workflow-policy guard tests so malicious exact versions and unsafe Actions trust-boundary patterns do not re-enter.

The prompt

You are remediating CVE-2026-45321 / GHSA-g7cv-rxg3-hmpx, the
KEV-listed TanStack npm supply-chain compromise where 84 malicious versions
across 42 `@tanstack/*` packages exfiltrated credentials during install.
Produce exactly one output:

- A reviewer-ready PR/change request that removes affected TanStack versions,
  regenerates clean lockfiles, purges repository-controlled caches and mirrors,
  adds regression guards, audits GitHub Actions publishing boundaries, and
  documents credential-rotation/operator actions, or
- `TRIAGE.md` if this repository has no controlled npm dependency graph,
  cache, image, CI workflow, or release pipeline exposure that can be safely
  remediated here.

## Rules

- Scope only CVE-2026-45321 / GHSA-g7cv-rxg3-hmpx and directly related
  TanStack dependency, npm install, cache, mirror, and GitHub Actions publishing
  boundaries.
- Treat all tokens, SSH keys, cloud credentials, package-registry credentials,
  Kubernetes service-account tokens, Vault tokens, CI secrets, and developer
  workstation credentials reachable by install scripts as sensitive.
- Do not install, execute, import, run tests against, or sandbox-run the
  malicious package versions.
- Do not print, upload, diff, or preserve harvested secrets. Do not attempt to
  contact payload infrastructure.
- Do not delete unrelated dependencies, remove security controls, or disable
  tests to make the remediation appear clean.
- Do not auto-merge.

## Steps

1. Inventory npm package surfaces controlled by this repository: `package.json`,
   package manager lockfiles, workspaces, vendored modules, Dockerfiles, image
   build contexts, SBOMs, generated dependency reports, registry-mirror config,
   CI caches, and release workflows.
2. Search for all `@tanstack/*` packages and compare resolved versions against
   the exact malicious-version table in the SecurityRecipes entry for
   CVE-2026-45321.
3. If any exact malicious version is present, remove it from manifests and
   regenerate the lockfile from a clean environment with lifecycle scripts
   disabled until the dependency graph no longer resolves an affected version.
4. Upgrade affected packages to the first patched version or newer. If the
   repository cannot upgrade because of framework compatibility, stop with
   `TRIAGE.md` naming the blocker, owner, temporary containment, and follow-up
   date.
5. Delete repository-controlled `node_modules`, package-manager stores, CI
   workspaces, cache keys, build artifacts, and Docker layers that may contain
   the affected tarballs. For internal mirrors or proxy registries, invoke or
   draft the compromised-package cache-quarantine workflow with exact
   `name@version` coordinates.
6. Review CI and release logs for installs of affected versions on or after
   2026-05-11 19:20 UTC. Record which runners, jobs, workstations, and images
   were plausibly exposed. Do not fetch or display secrets from logs.
7. Draft the credential-rotation packet for every exposed environment:
   GitHub tokens, npm tokens, cloud credentials, SSH keys, Kubernetes
   service-account tokens, Vault tokens, package-registry credentials, and
   deployment credentials. Mark rotation as an operator action if this repo
   cannot perform it directly.
8. Audit GitHub Actions workflows for the enabling pattern:
   - `pull_request_target` that checks out fork-controlled refs or runs
     fork-controlled code;
   - caches shared between untrusted PR jobs and trusted release jobs;
   - broad `restore-keys` that allow cache fallback across trust zones;
   - publish workflows with `id-token: write` before build inputs are fixed;
   - npm trusted-publishing jobs that run after restoring untrusted caches.
9. Fix workflow trust boundaries where this repository owns them:
   - use `pull_request` for untrusted code execution;
   - keep `pull_request_target` limited to metadata-only actions;
   - segregate cache keys and cache scopes by trust zone;
   - remove broad fallback restore keys from release jobs;
   - move `id-token: write` to the minimal publish job;
   - build release artifacts from checked, immutable refs and clean dependency
     installs.
10. Add safe regression guards:
    - a dependency guard rejects every malicious exact version;
    - a workflow guard flags `pull_request_target` plus fork checkout or code
      execution;
    - a workflow guard flags release publishing jobs that restore untrusted
      caches while holding `id-token: write`;
    - a tarball-inspection fixture checks for the malicious optional dependency
      and `router_init.js` without executing scripts.
11. Add a PR body section named `CVE-2026-45321 operator actions` that states:
    - which `@tanstack/*` packages and versions were found;
    - which lockfiles, images, caches, and mirrors were regenerated or purged;
    - whether any CI or developer environment installed an affected version
      after 2026-05-11 19:20 UTC;
    - which credentials require rotation and who owns it;
    - which GitHub Actions trust-boundary issues were fixed or triaged;
    - which validation commands passed.
12. Run available validation: clean package install with scripts controlled,
    lockfile integrity checks, dependency guard tests, workflow-policy tests,
    unit tests, build, lint/typecheck, SBOM refresh, image build, and
    dependency/security scans.
13. Use PR title:
    `fix(sec): remediate CVE-2026-45321 TanStack compromise`.

## Stop conditions

- No controlled npm dependency graph, image, CI workflow, package mirror, or
  cache can contain an affected TanStack artifact.
- The only exposure is an externally owned build environment; write
  `TRIAGE.md` naming the owner, evidence, required rotation, and due date.
- Safe verification would require executing a malicious package version,
  contacting payload infrastructure, or exposing secrets.
- Credential rotation is required but cannot be done from this repository;
  document the rotation packet and stop short of claiming full remediation.
- Validation fails for unrelated pre-existing reasons; document those failures
  instead of broadening scope.

Verification - what the reviewer looks for

  • No repository-controlled manifest, lockfile, SBOM, image, generated report, cache policy, or registry mirror still references the exact malicious @tanstack/* versions.
  • The PR was generated from a clean dependency graph and did not execute lifecycle scripts for suspected malicious versions.
  • CI and developer install exposure was assessed against the 2026-05-11 malicious publish window, and credential rotation is either completed or explicitly assigned as an operator action.
  • GitHub Actions workflows do not let fork-controlled code poison caches that trusted release jobs restore before npm trusted publishing.
  • Regression guards cover both dependency coordinates and Actions trust-boundary patterns.

Watch for

  • Treating this as a simple package bump while leaving CI caches, mirrors, Docker layers, or developer package stores untouched.
  • Updating package.json but leaving an affected exact version in pnpm-lock, package-lock.json, yarn.lock, SBOM output, or a generated dependency report.
  • Running npm install without disabling scripts while investigating a suspected affected version.
  • Assuming a read-only GITHUB_TOKEN prevents Actions cache writes in pull_request_target jobs.
  • Leaving id-token: write on build jobs that restore caches or execute dependency-installed binaries before publish-time integrity checks.
  • Rotating npm tokens but forgetting cloud metadata credentials, SSH keys, Kubernetes service-account tokens, Vault tokens, GitHub CLI credentials, or package-registry tokens available to the install environment.

Output contract

Return one of:

  • A reviewer-ready PR/change request that removes exact malicious TanStack versions, regenerates clean lockfiles, purges controlled caches/mirrors, adds dependency and workflow-policy guards, hardens GitHub Actions trust-boundaries, and includes an operator credential-rotation packet.
  • TRIAGE.md when this repository has no controlled npm dependency graph, cache, image, CI workflow, package mirror, or release pipeline exposure that can be remediated here.

The output must list packages and versions found, lockfiles/images/caches changed, install exposure since 2026-05-11 19:20 UTC, credentials requiring rotation, workflow trust-boundary findings, validation commands, and remaining owners/due dates. It must not execute malicious package versions, contact payload infrastructure, preserve harvested secrets, or claim credential rotation is complete unless the repository actually performs it.

References