JSPM

@emstack/tanstack-supply-chain-checker

1.2.0
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 11
  • Score
    100M100P100Q92211F
  • License MIT

Detect and fix the mini-shai-hulud TanStack supply-chain attack (socket.dev/blog/tanstack-npm-packages-compromised-mini-shai-hulud-supply-chain-attack)

Package Exports

    This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@emstack/tanstack-supply-chain-checker) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

    Readme

    @emstack/tanstack-supply-chain-checker

    Detect and remediate the mini-shai-hulud TanStack supply-chain attack (disclosed May 11, 2026).

    Reference: socket.dev/blog/tanstack-npm-packages-compromised-mini-shai-hulud-supply-chain-attack

    Quick start

    npx @emstack/tanstack-supply-chain-checker

    No arguments → interactive mode. Guides through path input, project selection, and options step by step.

    ┌  tanstack-supply-chain-checker  mini-shai-hulud attack detector
    │
    ◆  Root path to scan
    │  ./my-monorepo
    │
    ◆  Select projects to scan
    │  ■ my-app        packages/app
    │  ■ my-lib        packages/lib
    │  □ legacy        packages/legacy
    │
    ◆  Auto-fix detected issues?
    │  No / Yes
    │
    ◆  Include node_modules in scan?
    │  No / Yes
    │
    ◇  Scanning my-app  2 critical, 1 high
    │  [CRITICAL] package.json
    │             injected-dependency: Injected malicious package "@tanstack/setup" found in dependencies
    │  [HIGH]     package.json
    │             compromised-version: Package "@opensearch-project/opensearch@3.5.3" matches known compromised version
    │
      ────────────────────────────────────────────────────────
      SECURITY SUMMARY
    
      Compromised packages (2)
        ● @tanstack/setup            package.json
        ● @opensearch-project/opensearch@3.5.3   package.json
    
      ────────────────────────────────────────────────────────
    
    ◇  Scanning my-lib  ✓ clean
    │
      SCAN SUMMARY
      my-app    2 critical, 1 high    packages/app
      my-lib    ✓ Clean               packages/lib

    Usage

    Interactive (default)

    npx @emstack/tanstack-supply-chain-checker          # auto-launches interactive
    npx @emstack/tanstack-supply-chain-checker -i       # explicit flag

    Discovers all package.json projects under the given root, lets you select which to scan, and walks through options with prompts.

    Non-interactive (CI / scripting)

    npx @emstack/tanstack-supply-chain-checker ./my-project
    npx @emstack/tanstack-supply-chain-checker ./my-project --fix
    npx @emstack/tanstack-supply-chain-checker . --include-node-modules
    npx @emstack/tanstack-supply-chain-checker . --json

    Flags

    Flag Description
    -i, --interactive Interactive mode (default when no args)
    --fix Auto-remove malicious files, clean package.json
    --include-node-modules Also scan inside node_modules (slow)
    --json Machine-readable output, exit 1 on findings
    --help Show help

    Report output

    After scanning, a SECURITY SUMMARY block groups findings by threat type so you can triage at a glance:

    ────────────────────────────────────────────────────────
      SECURITY SUMMARY
    
      Compromised packages (3)
        ● @tanstack/setup                   package.json
        ● @opensearch-project/opensearch@3.5.3   package.json
        ● @tanstack/router (router_init.js)     node_modules/...
    
      Malicious files (1)
        ● router_init.js                    router_init.js
    
      Backdoor hooks / tasks (1)
        ● scripts.prepare                   package.json
    
      Network IOCs in source (1)
        ● filev2.getsession.org             src/setup.ts
    
      Unauthorized git commits (1)
        ● a3f1bc9d2e44                      .git
    
    ────────────────────────────────────────────────────────

    Groups shown only when findings exist in that category. Bold label = package name, script key, or IOC string. Dim path = location in repo. Same summary printed per-project in interactive mode and aggregated across all projects at the end.

    What it detects

    Category Detail Auto-fixable
    Malicious payload files router_init.js, router_runtime.js, tanstack_runner.js — case-insensitive, anywhere in tree Yes
    Known SHA256 hashes 2 known payload hashes, checked against .js/.mjs/.cjs files Yes
    Persistence — Claude Code .claude/router_runtime.js, .claude/setup.mjs Yes
    Persistence — VS Code .vscode/setup.mjs Yes
    Injected dependency @tanstack/setup in any dep section Yes
    Malicious lifecycle hook prepare/postinstall referencing worm files (string and array form) Yes
    Compromised @tanstack package router_init.js inside installed package Yes
    Compromised version — other packages @opensearch-project/opensearch@3.5.3–3.8.0, @squawk/mcp@0.9.5, @squawk/weather@0.5.10, @squawk/flightplan@0.5.6 Manual
    Installed compromised package package.json inside node_modules matches known bad name + version Manual
    Network IOC in source .js/.ts files referencing filev2.getsession.org, git-tanstack.com Manual
    Malicious Claude hooks .claude/settings.json hooks referencing worm files Manual
    VS Code auto-run tasks .vscode/tasks.json with runOn: folderOpen Manual
    Unauthorized git commits Commits from claude@users.noreply.github.com Manual

    What --fix does

    • Deletes all confirmed malicious files
    • Strips @tanstack/setup from all package.json dependency sections
    • Removes malicious lifecycle scripts (handles both string and array form)
    • Writes package.json atomically (temp file → rename — no corruption risk)
    • Prints secrets-rotation checklist covering npm, GitHub, AWS (incl. OIDC), GCP, Azure, Docker, PyPI, Ruby, Rust, Vault, GPG
    • Prints git commands to audit unauthorized commits

    What requires manual action

    • .claude/settings.json hooks — requires human judgment before editing
    • .vscode/tasks.json auto-run tasks — inspect before deleting
    • Git history — revert specific commits after review
    • Secrets rotation — cannot be automated
    • OIDC federation revocation — GitHub repo settings
    • Compromised third-party package versions — pin to a clean version and reinstall
    • Network IOC references in source — inspect file, determine if injected

    Affected packages

    @tanstack — 84 compromised artifacts. Worm payload injected into router_init.js / router_runtime.js inside installed packages.

    Other npm packages (loaded at runtime from data/compromised-packages.csv — sourced from Socket.dev disclosure):

    Namespace Packages Versions
    @opensearch-project opensearch 3.5.3, 3.6.2, 3.7.0, 3.8.0
    @squawk airport-data, airports, airspace, airspace-data, airway-data, airways, fix-data, fixes, flight-math, flightplan, geo, icao-registry, icao-registry-data, mcp, navaid-data, navaids, notams, procedure-data, procedures, types, units, weather multiple (0.3.x – 0.9.x)
    @mistralai mistralai, mistralai-azure, mistralai-gcp 1.7.1–1.7.3, 2.2.2–2.2.4
    @uipath 45 packages (apollo-react, agent-sdk, robot, cli, …) single versions per package
    @tallyui components, connector-*, core, database, pos, storage-sqlite, theme 0.2.1–1.0.3
    @beproduct nestjs-auth 0.1.2–0.1.19
    @draftlab / @draftauth auth, auth-router, db, client, core 0.13.x–0.24.x
    @cap-js db-service, postgres, sqlite 2.2.2, 2.10.1
    @mesadev rest, saguaro, sdk 0.28.3, 0.4.22
    @ml-toolkit-ts preprocessing, xgboost 1.0.2–1.0.4
    @supersurkhet cli, sdk 0.0.2–0.0.7
    @taskflow-corp cli 0.1.24–0.1.29
    @tolka cli 1.0.2–1.0.6
    @dirigible-ai sdk 0.6.2, 0.6.3
    (unscoped) cross-stitch, git-branch-selector, git-git-git, ts-dna, wot-api, nextmove-mcp, cmux-agent-mcp, safe-action, ml-toolkit-ts, agentwork-cli, intercom-client, mbt various

    PyPI packages mistralai@2.4.6 and guardrails-ai@0.10.1 were also compromised but are outside the scope of this npm scanner.

    Updating the IOC package list

    Compromised package versions are loaded at runtime from data/compromised-packages.csv. To add new packages:

    1. Append rows to data/compromised-packages.csv using the same column format:
      Ecosystem,Namespace,Name,Version,Published,Detected
      npm,@example,package-name,1.2.3,,
    2. Run bun run build — no code changes needed.

    The scanner filters Ecosystem = npm and skips @tanstack (handled separately via file-based detection).

    Build & test

    bun install
    bun run build       # outputs dist/cli.js
    bun run validate    # integration tests (runs automatically on publish)
    bash test/smoke.sh  # end-to-end smoke test with harmless fixtures

    Contributing

    See CONTRIBUTING.md — especially the section on adding new IOCs.