TanStack Router Packages Hit by Mini Shai-Hulud TheBeautifulSandsOfTime Supply Chain Attack

Malicious TanStack Router packages provide updated Mini Shai-Hulud style worm attack with encrypted exfil of credentials and dead man's switch.

May 11th, 2026

TanStack has become foundational infrastructure in the modern open-source React ecosystem. What started as a set of focused utilities has evolved into a broader application platform that now influences how developers think about data fetching, routing, rendering, and full-stack architecture. Query has already reached mainstream adoption, while Router is gaining traction as teams move toward type-safe, loader-driven application design.

The recent compromise affecting dozens of TanStack Router and ecosystem packages is another reminder that attackers are aggressively targeting developer tooling rather than deployed application runtimes. In this case, the malicious packages abused install-time execution paths, hidden dependency resolution behavior, and heavily obfuscated payloads to steal GitHub tokens, cloud credentials, npm tokens, and other secrets directly from developer systems during package installation. Newer analysis also suggests the payload attempted to establish persistence mechanisms and deployed what appears to be a dead man’s switch tied to stolen GitHub credentials.

One of the more alarming details involves payload behavior referencing the string IfYouRevokeThisTokenItWillWipeTheComputerOfTheOwner, alongside token-monitoring activity that continuously validated stolen GitHub credentials against the GitHub API. Researchers also identified indicators tied to the beautifulmarchoftime and beautifulsandsoftime tokens, which appear associated with active and historical command-and-control beaconing behavior. Reported persistence mechanisms include user-level systemd services on Linux and LaunchAgents on macOS that periodically check whether stolen credentials remain valid and may trigger destructive cleanup behavior if tokens are revoked improperly.

The TanStack team published a postmortem on the origin of the compromise.

For Semgrep Customers

Semgrep has an advisory and rule to cover this so you can find to check your projects.

  1. Trigger a new scan if you haven't recently on your projects.

  2. Check the advisories page to see if any projects have installed these package versions recently:

    1. https://semgrep.dev/orgs/-/advisories/ssc-fc60ecdd-648a-460b-9632-618e8a1faf73

    2. https://semgrep.dev/orgs/-/advisories/ssc-8c6cceb0-5ccd-484b-8f90-4381d27a3627

    3. https://semgrep.dev/orgs/-/advisories/ssc-ffa4a734-c2b5-40e8-9d91-97f2dc406194

    4. https://semgrep.dev/orgs/-/advisories/ssc-72bb15d3-4047-4098-9e14-beb3f260d495

    5. https://semgrep.dev/orgs/-/advisories/ssc-ece2846d-737b-4ff0-ad1e-9787549a552a

    6. https://semgrep.dev/orgs/-/advisories/ssc-01cf6cf7-cb60-4b35-89ce-b67e4119e6fd

  3. Check your dependency filter for matches. If you see “No matching dependencies” you are not actively using the malicious dependency in any of your projects. If you did match, additional advice on remediation and indicators of compromise are below.

If you matched: Follow the remediation advice below.

Remediation Advice

Exercise caution when revoking potentially exposed GitHub tokens or cloud credentials on affected developer systems. Before rotating or revoking credentials, isolate the affected machine from the network, preserve forensic evidence if needed, and inspect for unauthorized persistence artifacts or scheduled processes. Teams should consider restoring developer environments from a known-good state rather than relying solely on credential rotation and package removal.

Analysis of the payload indicates it may install persistence mechanisms and a dead man’s switch, including a token-monitoring process that periodically validates stolen GitHub credentials and may trigger destructive behavior if the token is revoked: IfYouRevokeThisTokenItWillWipeTheComputerOfTheOwner.

On Linux systems this reportedly appears as a user-level systemd service, while on macOS it may register as a LaunchAgent.

Audit your repositories for the injected files listed in the IOCs below (.claude/ and .vscode/ directories with unexpected contents), and rotate any other package maintainer, cloud credentials or API keys that may have been present in the affected environment.

For additional advice about how to deal with supply chain attacks such as instituting cool down periods, pinning GitHub Actions to SHAs, and pinning versions in package lists; our standard advice is covered by posts such as:

Affected Packages

The following NPM packages and versions were observed to have the malicious payload:

- @beproduct/nestjs-auth@0.1.2

- @beproduct/nestjs-auth@0.1.3

- @beproduct/nestjs-auth@0.1.4

- @beproduct/nestjs-auth@0.1.5

- @beproduct/nestjs-auth@0.1.6

- @beproduct/nestjs-auth@0.1.7

- @beproduct/nestjs-auth@0.1.8

- @beproduct/nestjs-auth@0.1.9

- @beproduct/nestjs-auth@0.1.10

- @beproduct/nestjs-auth@0.1.11

- @beproduct/nestjs-auth@0.1.12

- @beproduct/nestjs-auth@0.1.13

- @beproduct/nestjs-auth@0.1.14

- @beproduct/nestjs-auth@0.1.15

- @beproduct/nestjs-auth@0.1.16

- @beproduct/nestjs-auth@0.1.17

- @beproduct/nestjs-auth@0.1.18

- @beproduct/nestjs-auth@0.1.19

- @cap-js/db-service@2.10.1

- @cap-js/postgres@2.2.2

- @cap-js/sqlite@2.2.2

- @dirigible-ai/sdk@0.6.2

- @dirigible-ai/sdk@0.6.3

- @draftauth/client@0.2.1

- @draftauth/client@0.2.2

- @draftauth/core@0.13.1

- @draftauth/core@0.13.2

- @draftlab/auth@0.24.1

- @draftlab/auth@0.24.2

- @draftlab/auth-router@0.5.1

- @draftlab/auth-router@0.5.2

- @draftlab/db@0.16.1

- @draftlab/db@0.16.2

- @mesadev/rest@0.28.3

- @mesadev/saguaro@0.4.22

- @mesadev/sdk@0.28.3

- @mistralai/mistralai@2.2.2

- @mistralai/mistralai@2.2.3

- @mistralai/mistralai@2.2.4

- @mistralai/mistralai-azure@1.7.1

- @mistralai/mistralai-azure@1.7.2

- @mistralai/mistralai-azure@1.7.3

- @mistralai/mistralai-gcp@1.7.1

- @mistralai/mistralai-gcp@1.7.2

- @mistralai/mistralai-gcp@1.7.3

- @ml-toolkit-ts/preprocessing@1.0.2

- @ml-toolkit-ts/preprocessing@1.0.3

- @ml-toolkit-ts/xgboost@1.0.3

- @ml-toolkit-ts/xgboost@1.0.4

- @opensearch-project/opensearch@3.5.3

- @opensearch-project/opensearch@3.6.2

- @opensearch-project/opensearch@3.7.0

- @opensearch-project/opensearch@3.8.0

- @squawk/airport-data@0.7.4

- @squawk/airport-data@0.7.5

- @squawk/airport-data@0.7.6

- @squawk/airport-data@0.7.7

- @squawk/airport-data@0.7.8

- @squawk/airports@0.6.2

- @squawk/airports@0.6.3

- @squawk/airports@0.6.4

- @squawk/airports@0.6.5

- @squawk/airports@0.6.6

- @squawk/airspace@0.8.1

- @squawk/airspace@0.8.2

- @squawk/airspace@0.8.3

- @squawk/airspace@0.8.4

- @squawk/airspace@0.8.5

- @squawk/airspace-data@0.5.3

- @squawk/airspace-data@0.5.4

- @squawk/airspace-data@0.5.5

- @squawk/airspace-data@0.5.6

- @squawk/airspace-data@0.5.7

- @squawk/airway-data@0.5.4

- @squawk/airway-data@0.5.5

- @squawk/airway-data@0.5.6

- @squawk/airway-data@0.5.7

- @squawk/airway-data@0.5.8

- @squawk/airways@0.4.2

- @squawk/airways@0.4.3

- @squawk/airways@0.4.4

- @squawk/airways@0.4.5

- @squawk/airways@0.4.6

- @squawk/fix-data@0.6.4

- @squawk/fix-data@0.6.5

- @squawk/fix-data@0.6.6

- @squawk/fix-data@0.6.7

- @squawk/fix-data@0.6.8

- @squawk/fixes@0.3.2

- @squawk/fixes@0.3.3

- @squawk/fixes@0.3.4

- @squawk/fixes@0.3.5

- @squawk/fixes@0.3.6

- @squawk/flight-math@0.5.4

- @squawk/flight-math@0.5.5

- @squawk/flight-math@0.5.6

- @squawk/flight-math@0.5.7

- @squawk/flight-math@0.5.8

- @squawk/flightplan@0.5.2

- @squawk/flightplan@0.5.3

- @squawk/flightplan@0.5.4

- @squawk/flightplan@0.5.5

- @squawk/flightplan@0.5.6

- @squawk/geo@0.4.4

- @squawk/geo@0.4.5

- @squawk/geo@0.4.6

- @squawk/geo@0.4.7

- @squawk/geo@0.4.8

- @squawk/icao-registry@0.5.2

- @squawk/icao-registry@0.5.3

- @squawk/icao-registry@0.5.4

- @squawk/icao-registry@0.5.5

- @squawk/icao-registry@0.5.6

- @squawk/icao-registry-data@0.8.4

- @squawk/icao-registry-data@0.8.5

- @squawk/icao-registry-data@0.8.6

- @squawk/icao-registry-data@0.8.7

- @squawk/icao-registry-data@0.8.8

- @squawk/mcp@0.9.1

- @squawk/mcp@0.9.2

- @squawk/mcp@0.9.3

- @squawk/mcp@0.9.4

- @squawk/mcp@0.9.5

- @squawk/navaid-data@0.6.4

- @squawk/navaid-data@0.6.5

- @squawk/navaid-data@0.6.6

- @squawk/navaid-data@0.6.7

- @squawk/navaid-data@0.6.8

- @squawk/navaids@0.4.2

- @squawk/navaids@0.4.3

- @squawk/navaids@0.4.4

- @squawk/navaids@0.4.5

- @squawk/navaids@0.4.6

- @squawk/notams@0.3.6

- @squawk/notams@0.3.7

- @squawk/notams@0.3.8

- @squawk/notams@0.3.9

- @squawk/notams@0.3.10

- @squawk/procedure-data@0.7.3

- @squawk/procedure-data@0.7.4

- @squawk/procedure-data@0.7.5

- @squawk/procedure-data@0.7.6

- @squawk/procedure-data@0.7.7

- @squawk/procedures@0.5.2

- @squawk/procedures@0.5.3

- @squawk/procedures@0.5.4

- @squawk/procedures@0.5.5

- @squawk/procedures@0.5.6

- @squawk/types@0.8.1

- @squawk/types@0.8.2

- @squawk/types@0.8.3

- @squawk/types@0.8.4

- @squawk/types@0.8.5

- @squawk/units@0.4.3

- @squawk/units@0.4.4

- @squawk/units@0.4.5

- @squawk/units@0.4.6

- @squawk/units@0.4.7

- @squawk/weather@0.5.6

- @squawk/weather@0.5.7

- @squawk/weather@0.5.8

- @squawk/weather@0.5.9

- @squawk/weather@0.5.10

- @supersurkhet/cli@0.0.2

- @supersurkhet/cli@0.0.3

- @supersurkhet/cli@0.0.4

- @supersurkhet/cli@0.0.5

- @supersurkhet/cli@0.0.6

- @supersurkhet/cli@0.0.7

- @supersurkhet/sdk@0.0.2

- @supersurkhet/sdk@0.0.3

- @supersurkhet/sdk@0.0.4

- @supersurkhet/sdk@0.0.5

- @supersurkhet/sdk@0.0.6

- @supersurkhet/sdk@0.0.7

- @tallyui/components@1.0.1

- @tallyui/components@1.0.2

- @tallyui/components@1.0.3

- @tallyui/connector-medusa@1.0.1

- @tallyui/connector-medusa@1.0.2

- @tallyui/connector-medusa@1.0.3

- @tallyui/connector-shopify@1.0.1

- @tallyui/connector-shopify@1.0.2

- @tallyui/connector-shopify@1.0.3

- @tallyui/connector-vendure@1.0.1

- @tallyui/connector-vendure@1.0.2

- @tallyui/connector-vendure@1.0.3

- @tallyui/connector-woocommerce@1.0.1

- @tallyui/connector-woocommerce@1.0.2

- @tallyui/connector-woocommerce@1.0.3

- @tallyui/core@0.2.1

- @tallyui/core@0.2.2

- @tallyui/core@0.2.3

- @tallyui/database@1.0.1

- @tallyui/database@1.0.2

- @tallyui/database@1.0.3

- @tallyui/pos@0.1.1

- @tallyui/pos@0.1.2

- @tallyui/pos@0.1.3

- @tallyui/storage-sqlite@0.2.1

- @tallyui/storage-sqlite@0.2.2

- @tallyui/storage-sqlite@0.2.3

- @tallyui/theme@0.2.1

- @tallyui/theme@0.2.2

- @tallyui/theme@0.2.3

- @tanstack/arktype-adapter@1.166.12

- @tanstack/arktype-adapter@1.166.15

- @tanstack/eslint-plugin-router@1.161.9

- @tanstack/eslint-plugin-router@1.161.12

- @tanstack/eslint-plugin-start@0.0.4

- @tanstack/eslint-plugin-start@0.0.7

- @tanstack/history@1.161.9

- @tanstack/history@1.161.12

- @tanstack/nitro-v2-vite-plugin@1.154.12

- @tanstack/nitro-v2-vite-plugin@1.154.15

- @tanstack/react-router@1.169.5

- @tanstack/react-router@1.169.8

- @tanstack/react-router-devtools@1.166.16

- @tanstack/react-router-devtools@1.166.19

- @tanstack/react-router-ssr-query@1.166.15

- @tanstack/react-router-ssr-query@1.166.18

- @tanstack/react-start@1.167.68

- @tanstack/react-start@1.167.71

- @tanstack/react-start-client@1.166.51

- @tanstack/react-start-client@1.166.54

- @tanstack/react-start-rsc@0.0.47

- @tanstack/react-start-rsc@0.0.50

- @tanstack/react-start-server@1.166.55

- @tanstack/react-start-server@1.166.58

- @tanstack/router-cli@1.166.46

- @tanstack/router-cli@1.166.49

- @tanstack/router-core@1.169.5

- @tanstack/router-core@1.169.8

- @tanstack/router-devtools@1.166.16

- @tanstack/router-devtools@1.166.19

- @tanstack/router-devtools-core@1.167.6

- @tanstack/router-devtools-core@1.167.9

- @tanstack/router-generator@1.166.45

- @tanstack/router-generator@1.166.48

- @tanstack/router-plugin@1.167.38

- @tanstack/router-plugin@1.167.41

- @tanstack/router-ssr-query-core@1.168.3

- @tanstack/router-ssr-query-core@1.168.6

- @tanstack/router-utils@1.161.11

- @tanstack/router-utils@1.161.14

- @tanstack/router-vite-plugin@1.166.53

- @tanstack/router-vite-plugin@1.166.56

- @tanstack/solid-router@1.169.5

- @tanstack/solid-router@1.169.8

- @tanstack/solid-router-devtools@1.166.16

- @tanstack/solid-router-devtools@1.166.19

- @tanstack/solid-router-ssr-query@1.166.15

- @tanstack/solid-router-ssr-query@1.166.18

- @tanstack/solid-start@1.167.65

- @tanstack/solid-start@1.167.68

- @tanstack/solid-start-client@1.166.50

- @tanstack/solid-start-client@1.166.53

- @tanstack/solid-start-server@1.166.54

- @tanstack/solid-start-server@1.166.57

- @tanstack/start-client-core@1.168.5

- @tanstack/start-client-core@1.168.8

- @tanstack/start-fn-stubs@1.161.9

- @tanstack/start-fn-stubs@1.161.12

- @tanstack/start-plugin-core@1.169.23

- @tanstack/start-plugin-core@1.169.26

- @tanstack/start-server-core@1.167.33

- @tanstack/start-server-core@1.167.36

- @tanstack/start-static-server-functions@1.166.44

- @tanstack/start-static-server-functions@1.166.47

- @tanstack/start-storage-context@1.166.38

- @tanstack/start-storage-context@1.166.41

- @tanstack/valibot-adapter@1.166.12

- @tanstack/valibot-adapter@1.166.15

- @tanstack/virtual-file-routes@1.161.10

- @tanstack/virtual-file-routes@1.161.13

- @tanstack/vue-router@1.169.5

- @tanstack/vue-router@1.169.8

- @tanstack/vue-router-devtools@1.166.16

- @tanstack/vue-router-devtools@1.166.19

- @tanstack/vue-router-ssr-query@1.166.15

- @tanstack/vue-router-ssr-query@1.166.18

- @tanstack/vue-start@1.167.61

- @tanstack/vue-start@1.167.64

- @tanstack/vue-start-client@1.166.46

- @tanstack/vue-start-client@1.166.49

- @tanstack/vue-start-server@1.166.50

- @tanstack/vue-start-server@1.166.53

- @tanstack/zod-adapter@1.166.12

- @tanstack/zod-adapter@1.166.15

- @taskflow-corp/cli@0.1.24

- @taskflow-corp/cli@0.1.25

- @taskflow-corp/cli@0.1.26

- @taskflow-corp/cli@0.1.27

- @taskflow-corp/cli@0.1.28

- @taskflow-corp/cli@0.1.29

- @tolka/cli@1.0.2

- @tolka/cli@1.0.3

- @tolka/cli@1.0.4

- @tolka/cli@1.0.5

- @tolka/cli@1.0.6

- @uipath/access-policy-sdk@0.3.1

- @uipath/access-policy-tool@0.3.1

- @uipath/admin-tool@0.1.1

- @uipath/agent-sdk@1.0.2

- @uipath/agent-tool@1.0.1

- @uipath/agent.sdk@0.0.18

- @uipath/aops-policy-tool@0.3.1

- @uipath/ap-chat@1.5.7

- @uipath/api-workflow-tool@1.0.1

- @uipath/apollo-core@5.9.2

- @uipath/apollo-react@4.24.5

- @uipath/apollo-wind@2.16.2

- @uipath/auth@1.0.1

- @uipath/case-tool@1.0.1

- @uipath/cli@1.0.1

- @uipath/codedagent-tool@1.0.1

- @uipath/codedagents-tool@0.1.12

- @uipath/codedapp-tool@1.0.1

- @uipath/common@1.0.1

- @uipath/context-grounding-tool@0.1.1

- @uipath/data-fabric-tool@1.0.2

- @uipath/docsai-tool@1.0.1

- @uipath/filesystem@1.0.1

- @uipath/flow-tool@1.0.2

- @uipath/functions-tool@1.0.1

- @uipath/gov-tool@0.3.1

- @uipath/identity-tool@0.1.1

- @uipath/insights-sdk@1.0.1

- @uipath/insights-tool@1.0.1

- @uipath/integrationservice-sdk@1.0.2

- @uipath/integrationservice-tool@1.0.2

- @uipath/llmgw-tool@1.0.1

- @uipath/maestro-sdk@1.0.1

- @uipath/maestro-tool@1.0.1

- @uipath/orchestrator-tool@1.0.1

- @uipath/packager-tool-apiworkflow@0.0.19

- @uipath/packager-tool-bpmn@0.0.9

- @uipath/packager-tool-case@0.0.9

- @uipath/packager-tool-connector@0.0.19

- @uipath/packager-tool-flow@0.0.19

- @uipath/packager-tool-functions@0.1.1

- @uipath/packager-tool-webapp@1.0.6

- @uipath/packager-tool-workflowcompiler@0.0.16

- @uipath/packager-tool-workflowcompiler-browser@0.0.34

- @uipath/platform-tool@1.0.1

- @uipath/project-packager@1.1.16

- @uipath/resource-tool@1.0.1

- @uipath/resourcecatalog-tool@0.1.1

- @uipath/resources-tool@0.1.11

- @uipath/robot@1.3.4

- @uipath/rpa-legacy-tool@1.0.1

- @uipath/rpa-tool@0.9.5

- @uipath/solution-packager@0.0.35

- @uipath/solution-tool@1.0.1

- @uipath/solutionpackager-sdk@1.0.11

- @uipath/solutionpackager-tool-core@0.0.34

- @uipath/tasks-tool@1.0.1

- @uipath/telemetry@0.0.7

- @uipath/test-manager-tool@1.0.2

- @uipath/tool-workflowcompiler@0.0.12

- @uipath/traces-tool@1.0.1

- @uipath/ui-widgets-multi-file-upload@1.0.1

- @uipath/uipath-python-bridge@1.0.1

- @uipath/vertical-solutions-tool@1.0.1

- @uipath/vss@0.1.6

- @uipath/widget.sdk@1.2.3

- agentwork-cli@0.1.4

- agentwork-cli@0.1.5

- cmux-agent-mcp@0.1.3

- cmux-agent-mcp@0.1.4

- cmux-agent-mcp@0.1.5

- cmux-agent-mcp@0.1.6

- cmux-agent-mcp@0.1.7

- cmux-agent-mcp@0.1.8

- cross-stitch@1.1.3

- cross-stitch@1.1.4

- cross-stitch@1.1.5

- cross-stitch@1.1.6

- cross-stitch@1.1.7

- git-branch-selector@1.3.3

- git-branch-selector@1.3.4

- git-branch-selector@1.3.5

- git-branch-selector@1.3.6

- git-branch-selector@1.3.7

- git-git-git@1.0.8

- git-git-git@1.0.9

- git-git-git@1.0.10

- git-git-git@1.0.11

- git-git-git@1.0.12

- mbt@1.2.48

- ml-toolkit-ts@1.0.4

- ml-toolkit-ts@1.0.5

- nextmove-mcp@0.1.3

- nextmove-mcp@0.1.4

- nextmove-mcp@0.1.5

- nextmove-mcp@0.1.6

- nextmove-mcp@0.1.7

- safe-action@0.8.3

- safe-action@0.8.4

- ts-dna@3.0.1

- ts-dna@3.0.2

- ts-dna@3.0.3

- ts-dna@3.0.4

- ts-dna@3.0.5

- wot-api@0.8.1

- wot-api@0.8.2

- wot-api@0.8.3

- wot-api@0.8.4

- guardrails-ai@0.10.1

- mistralai@2.4.6

See TanStack Issue #7383 for the initial report and details.

Indicators of Compromise

Domains / C2 Servers

Search GitHub for commits containing thebeautifulmarchoftime. Any hit that also contains thebeautifulsandsoftime token is an active and historical C2 domain beacon.

- filev2.getsession.org

Files / System Artifacts

- router_init.js

Credits

StepSecurity discovered the malware and has made reports to the maintainers of active projects to have the packages removed from NPM dramatically shrinking the window of exposure.