Skip to content

Pin @tanstack/history to avoid compromised npm versions#3285

Merged
pfefferle merged 3 commits into
trunkfrom
fix/pin-tanstack-history-supply-chain
May 12, 2026
Merged

Pin @tanstack/history to avoid compromised npm versions#3285
pfefferle merged 3 commits into
trunkfrom
fix/pin-tanstack-history-supply-chain

Conversation

@pfefferle
Copy link
Copy Markdown
Member

@pfefferle pfefferle commented May 12, 2026

Proposed changes:

Forward-defensive pin against the recent TanStack npm supply-chain attack ("mini-Shai-Hulud") flagged in GHSA-rmmr-r34h-pfm5 and reported by Socket.dev. Versions 1.161.9 and 1.161.12 of @tanstack/history contain malware; 1.161.6 (currently resolved transitively by @tanstack/react-router@^1.169.2) predates both and is safe.

Changes:

  • package.json — add an overrides block pinning @tanstack/history to 1.161.6, with an _overrides_comment documenting GHSA-rmmr-r34h-pfm5 and the remove-when condition (a clean TanStack release above 1.161.12).
  • .github/workflows/jest.yml + .github/workflows/playwright.yml — add a post-npm ci step that reads the installed version of @tanstack/history out of node_modules and fails the build with a GitHub ::error:: annotation if it isn't 1.161.6. Belt-and-suspenders if a future npm install, npm update, or dependabot bump ever drifts the resolution.

Indicators of compromise verified absent from the repo and node_modules:

  • Files: router_init.js, router_runtime.js, tanstack_runner.js, .claude/router_runtime.js, .claude/setup.mjs, .vscode/setup.mjs, and the malware variant of .vscode/tasks.json. The existing .claude/settings.json and .vscode/settings.json are the legitimate IDE configs.
  • Exfiltration endpoint: filev2.getsession.org / getsession.org.
  • Commits authored as claude@users.noreply.github.com.
  • SHA256 ab4fcadaec49c03278063dd269ea5eef82d24f2124a8e15d7b90f2fa8601266c (the malicious router_init.js).

Also confirmed: no @opensearch-project/opensearch@3.5.3/3.6.2/3.7.0/3.8.0, no @squawk/mcp@0.9.5, no @squawk/weather@0.5.10, no @squawk/flightplan@0.5.6 anywhere in the dependency tree.

Note on npm audit:

npm audit will continue to report @tanstack/history as critical because the GHSA advisory has a catch-all >=0 vulnerability range alongside the two specific compromised versions. This is upstream noise that resolves once TanStack publishes a clean version and the advisory is narrowed. The CI assertion (/jest.yml, /playwright.yml) is the real gate.

Other information:

  • Have you written new tests for your changes, if applicable?

Testing instructions:

  • npm install — verify the install completes without errors.
  • node -p "require('./node_modules/@tanstack/history/package.json').version" — should output 1.161.6.
  • On a PR that mutates package.json or package-lock.json, the jest and playwright workflows now run an extra "Verify @tanstack/history pin" step. Confirm it passes today and would fail (locally simulated) if the version drifted.

Changelog entry

Changelog Entry Details

Significance

  • Patch

Type

  • Security

Message

Block a recently compromised JavaScript dependency from being installed during builds.

GHSA-rmmr-r34h-pfm5 names versions 1.161.9 and 1.161.12 of
@tanstack/history as containing malware (part of the recent
"mini-Shai-Hulud" supply-chain attack on TanStack npm packages).

The plugin currently resolves @tanstack/history transitively to
1.161.6 — published before the compromise, malware-free. None of the
indicators of compromise (router_init.js, router_runtime.js,
tanstack_runner.js, filev2.getsession.org references, fake Claude
commits) are present in the repo or node_modules.

Add an npm `overrides` entry pinning the transitive dependency to
1.161.6 so a future `npm install`, `npm update`, or dependabot bump
of @tanstack/react-router cannot resolve into the malicious versions.
The pin can be relaxed once TanStack publishes a clean version above
1.161.12.
Copilot AI review requested due to automatic review settings May 12, 2026 10:10
@pfefferle pfefferle self-assigned this May 12, 2026
@pfefferle pfefferle requested a review from a team May 12, 2026 10:10
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Pins @tanstack/history via npm overrides to prevent future installs from resolving to known-compromised versions referenced in GHSA-rmmr-r34h-pfm5, providing a forward-defensive supply-chain hardening measure for the repo’s JS toolchain.

Changes:

  • Add an npm overrides rule to force @tanstack/history to 1.161.6.
  • Add a security patch changelog entry describing the dependency pin.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
package.json Adds an npm overrides pin for @tanstack/history to prevent compromised versions from being installed.
.github/changelog/pin-tanstack-history-supply-chain Records the security patch change in the project’s changelogger format.

Audit findings on PR #3285:

- (Medium / M-1) No CI enforcement. Add a step to jest.yml and
  playwright.yml that reads the installed version of @tanstack/history
  out of node_modules and fails with a GitHub `::error::` annotation
  if it isn't `1.161.6`. Belt-and-suspenders if `npm ci` ever drifts
  from the committed lockfile.

- (Documentation) Add an `_overrides_comment` key in package.json so
  future maintainers know what the pin is for and when it is safe to
  remove (clean TanStack release above 1.161.12).

The auditor's H-1 finding about `package-lock.json` not encoding the
`overrides` block was investigated but skipped: npm 11.7 only writes
the lockfile-level overrides metadata when resolution changes, and
the lockfile already pins history to 1.161.6 transitively, so
`npm ci` is deterministic against the safe version today. The new CI
assertion catches any future drift regardless of whether the override
metadata is present in the lockfile.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

Comment thread .github/workflows/playwright.yml
Comment thread .github/workflows/jest.yml
Copilot review on PR #3285: hardcoding `1.161.6` in the CI workflows
duplicates the source of truth in package.json. When the override is
eventually relaxed (TanStack ships a clean version above 1.161.12),
someone has to remember to update CI too.

Read the expected version from `package.json#overrides` and compare
the installed copy in node_modules against it. The CI step now
detects resolver drift (the override silently failing for any reason)
without coupling to the specific safe version, so the maintainer only
needs to touch one place when adjusting the pin.

Trade-off: this no longer asserts "the override value is 1.161.6
specifically". A future PR that changes the override to a still-bad
version would pass CI. That decision moves to PR review by humans,
which is where it belongs anyway — CI's job is to catch unintended
drift, not to validate intentional human choices about safe versions.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

@pfefferle pfefferle merged commit 5bd03fc into trunk May 12, 2026
11 checks passed
@pfefferle pfefferle deleted the fix/pin-tanstack-history-supply-chain branch May 12, 2026 10:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants