Pin @tanstack/history to avoid compromised npm versions#3285
Merged
Conversation
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.
There was a problem hiding this comment.
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
overridesrule to force@tanstack/historyto1.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.
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.9and1.161.12of@tanstack/historycontain malware;1.161.6(currently resolved transitively by@tanstack/react-router@^1.169.2) predates both and is safe.Changes:
package.json— add anoverridesblock pinning@tanstack/historyto1.161.6, with an_overrides_commentdocumenting GHSA-rmmr-r34h-pfm5 and the remove-when condition (a clean TanStack release above1.161.12)..github/workflows/jest.yml+.github/workflows/playwright.yml— add a post-npm cistep that reads the installed version of@tanstack/historyout ofnode_modulesand fails the build with a GitHub::error::annotation if it isn't1.161.6. Belt-and-suspenders if a futurenpm install,npm update, or dependabot bump ever drifts the resolution.Indicators of compromise verified absent from the repo and
node_modules: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.jsonand.vscode/settings.jsonare the legitimate IDE configs.filev2.getsession.org/getsession.org.claude@users.noreply.github.com.ab4fcadaec49c03278063dd269ea5eef82d24f2124a8e15d7b90f2fa8601266c(the maliciousrouter_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.6anywhere in the dependency tree.Note on
npm audit:npm auditwill continue to report@tanstack/historyas critical because the GHSA advisory has a catch-all>=0vulnerability 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:
Testing instructions:
npm install— verify the install completes without errors.node -p "require('./node_modules/@tanstack/history/package.json').version"— should output1.161.6.package.jsonorpackage-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
Type
Message
Block a recently compromised JavaScript dependency from being installed during builds.