Mini Shai-Hulud Self-Propagating Software Supply Chain Worm

Mini Shai-Hulud is a highly sophisticated, self-propagating software supply chain worm targeting npm and PyPI ecosystems. Attributed to the TeamPCP threat actor group, it exploits CI/CD pipelines to harvest credentials and forge SLSA Build Level 3 provenance signatures.

Date:
Severity:
critical
Sources:
7
#npm#pypi#supply-chain#worm#teampcp#slsa#credentials-theft

Executive Summary

In late April and May 2026, a highly sophisticated, self-propagating supply chain worm designated “Mini Shai-Hulud” hit the npm and PyPI package registries. Attributed to the threat actor group TeamPCP, the worm automates credential harvesting, lateral movement, and package poisoning. The campaign exploits misconfigured CI/CD pipelines (specifically via pull_request_target triggers and GitHub Actions cache poisoning) to steal short-lived OIDC tokens. It then uses these tokens to sign malicious updates with valid SLSA Build Level 3 provenance badges via Sigstore and publish them directly to registries. Notable compromises include @tanstack npm packages, Alibaba’s @antv data visualization suite, SAP’s Cloud Application Programming Model (CAP) developer packages, and SDKs associated with Mistral AI, UiPath, and AWS OpenSearch-py. The worm contains a defensive “dead-man switch” that executes a destructive command (rm -rf /*) if it detects that its stolen credentials have been revoked or if it is running in a sandbox environment. Defenders must treat affected systems as fully compromised and immediately rotate all credentials, remove IDE workspace and AI assistant persistence hooks, and configure package managers to ignore install lifecycle scripts.

Key Facts

threat_type: malicious package, CI/CD compromise, credential theft, self-replicating worm, build provenance failure, artifact tampering
ecosystem: npm, PyPI
registry: npm registry, PyPI
affected_packages:
  - "@tanstack/*"
  - "@antv/*"
  - "@sap/cds"
  - "@sap/cds-dk"
  - "opensearch-py"
  - "lite-llm"
  - "nx-console"
malicious_versions:
  - "@tanstack/* (84 versions across 42 packages on May 11, 2026)"
  - "@antv/* (over 300 packages)"
  - "nx-console@18.95.0"
fixed_versions:
  - "@tanstack/* (deprecated and removed on May 11, 2026)"
  - "nx-console@18.95.1"
  - "@antv/* (subsequent clean versions)"
safe_versions:
  - "Pre-compromise versions and subsequent patch releases"
exposure_window: 2026-04-20 to 2026-05-23 (specifically May 11, 2026, 19:20 - 19:26 UTC for TanStack)
execution_trigger: Install-time execution via preinstall/postinstall scripts (router_init.js or setup.mjs)
primary_impact: CI/CD & cloud credential theft, lateral self-propagation, development workspace hijack, potential destructive system wipe
known_iocs:
  - "filev2.getsession[.]org"
  - "api.masscan[.]cloud"
  - "git-tanstack[.]com"
  - "t.m-kosche[.]com"
  - "ab4fcadaec49c03278063dd269ea5eef82d24f2124a8e15d7b90f2fa8601266c"
  - "router_init.js"
  - "setup_bun.js"
  - "bun_environment.js"
  - "transformers.pyz"
  - "gh-token-monitor"
confidence: high
canonical_source: https://tanstack.com/blog/postmortem-cve-2026-45321

Source Confidence & Evidence Mapping

  • confirmed:
    • Incident involving the TanStack npm packages between 19:20 and 19:26 UTC on May 11, 2026, where 84 malicious versions across 42 packages were published via hijacked OIDC tokens TanStack Blog.
    • The exploit mechanism chained a pull_request_target misconfiguration, cache poisoning, and memory extraction of GitHub Actions OIDC tokens to publish the packages SentinelOne.
    • TeamPCP was identified as the threat actor group responsible, utilizing Dune-themed repositories for dead-drop exfiltration of credentials Tenable.
    • The malicious payloads exfiltrated highly sensitive developer tokens, cloud credentials (AWS/GCP/Azure), Kubernetes secrets, OIDC tokens, and SSH keys Endor Labs.
  • likely:
    • The execution of Bun runtime smuggling where the malware downloads setup_bun.js to bypass traditional Node.js static scanners and run obfuscated payloads under the Bun engine Endor Labs.
    • The use of OIDC tokens within a trusted runner context to forge valid SLSA Build Level 3 provenance badges through Sigstore, creating cryptographically “verified” malicious releases Wiz.io.
  • unclear:
    • The exact number of downstream developer systems fully wiped by the “dead-man switch” payload (rm -rf /*) after credential revocation was initiated by security teams Microsoft Threat Intelligence.
  • not_observed:
    • Claims that npm or PyPI registry infrastructure was directly breached; all publishes resulted from OIDC token/credential exfiltration from developer environments and CI/CD pipelines TanStack Blog.

Timeline

  • 2026-04-20T00:00:00Z First anomalous publishes identified in the npm registry targeting enterprise developer utilities (specifically SAP developer packages) Endor Labs.
  • 2026-04-24T00:00:00Z Endor Labs identifies the initial wave, tracing it to stolen npm publishing credentials. The malware payload is observed downloading the Bun runtime to evade standard analysis tools Endor Labs.
  • 2026-05-10T00:00:00Z The worm spreads aggressively to high-profile developer packages including @tanstack, @antv, and SDKs under Mistral AI, UiPath, and OpenSearch Tenable.
  • 2026-05-11T19:20:00Z Attacker publishes 84 malicious versions across 42 @tanstack/* packages on npm TanStack Blog.
  • 2026-05-11T19:26:00Z Publishing of malicious @tanstack versions completes TanStack Blog.
  • 2026-05-12T00:00:00Z Wiz and Palo Alto Networks disclose that the malware is utilizing GitHub Actions cache poisoning and forging Sigstore provenance signatures to bypass CI/CD security filters Wiz.io.
  • 2026-05-19T00:00:00Z Microsoft and Zscaler publish detailed hunting guides for persistent IDE hooks and LaunchAgents deployed by the worm Microsoft Threat Intelligence.
  • 2026-05-23T01:00:00Z Nx Console release 18.95.1 is published to patch downstream contamination resulting from the compromise of a contributor’s hijacked token SentinelOne.

What Happened

In late April 2026, the TeamPCP threat actor group launched the “Mini Shai-Hulud” supply chain campaign, targeting widely used npm and PyPI developer dependencies Endor Labs. The campaign escalated dramatically on May 11, 2026, when the worm compromised the @tanstack npm scope, publishing 84 poisoned versions of 42 libraries, including @tanstack/router and @tanstack/react-query TanStack Blog.

Instead of stealing static npm credentials, the worm targeted the repository’s GitHub Actions pipeline SentinelOne. By submitting a malicious pull request to the TanStack/router repository, the worm triggered a misconfigured pull_request_target workflow SentinelOne. Due to a cache poisoning vulnerability where fork and base workflows shared execution caches, the attacker poisoned the base branch’s cache SentinelOne. When the trusted base workflow executed, it read the poisoned cache, allowing the worm to inject malicious code directly into the runner environment SentinelOne.

The worm then extracted the runner’s OpenID Connect (OIDC) token from active system memory Wiz.io. This short-lived OIDC token is trusted by the npm registry as a federated publisher identity Wiz.io. Using this token, the attacker signed the malicious release with Sigstore, obtaining a valid SLSA Build Level 3 provenance badge Wiz.io. This caused automated compliance tools and security scanners to trust the artifact’s lineage since the signature and provenance matched the official, legitimate GitHub Actions pipeline Wiz.io.

Once published, any developer executing npm install for the affected packages fell victim Endor Labs. The package lifecycle hooks executed a script that scraped host memory, environment variables, local cloud configurations, and personal access tokens Endor Labs. These stolen secrets were exfiltrated back to TeamPCP by creating public, encrypted repositories on the developer’s own hijacked GitHub account, named with distinct Dune-themed concepts to avoid detection Tenable.

Technical Analysis

Initial Access

The primary vector for initial access in the high-profile TanStack breach was the exploitation of a pull_request_target misconfiguration combined with GitHub Actions cache poisoning SentinelOne. An external pull request triggered the workflow in a context that had access to elevated repository secrets or OIDC trusted-publishing privileges SentinelOne. The attacker exploited a weakness where the dependency or build cache was shared between untrusted forks and trusted base runs, enabling cache poisoning SentinelOne.

Package or Artifact Manipulation

Once execution within the runner was achieved, the worm injected the script router_init.js (for npm) or setup.mjs directly into the package structure before release generation TanStack Blog. In the PyPI ecosystem, a similar payload named transformers.pyz was added to standard Python wheels Endor Labs. The attacker manipulated the package manifests (package.json) to register these files as preinstall or postinstall lifecycle hooks Endor Labs.

Execution Trigger

When downstream developers ran dependency installation commands like npm install or pip install, the package manager automatically executed the lifecycle script under administrative or user privileges Endor Labs. In Python environments, the payload triggered during wheel unpacking or package import time Endor Labs.

Payload Behavior

The malware checks the host environment to determine its runtime:

  1. Bun Runtime Smuggling: It searches for the bun binary. If missing, it downloads a lightweight standalone Bun engine (setup_bun.js) from an attacker-controlled staging server Endor Labs. The main payload is executed inside Bun rather than Node.js, successfully bypassing security monitors that hook only Node.js processes or analyze standard V8 engine calls Endor Labs.
  2. Credential Harvesting: The script scans the system for cloud credentials (AWS keys, Google Cloud JSON files, Azure profiles), container keys (Kubernetes secrets), .npmrc registry publishing tokens, SSH private keys, and environment variables Endor Labs.
  3. IDE and Coding Assistant Hijacking: To establish deep local persistence, the worm targets developer tools Microsoft Threat Intelligence. It appends malicious run tasks to the developer’s .vscode/tasks.json file so that opening the workspace triggers secret exfiltration Microsoft Threat Intelligence. It also places a wrapper inside .claude/settings.json to intercept inputs and commands passed to AI coding tools, monitoring for project structure and secrets Microsoft Threat Intelligence.
  4. OS Persistence: It installs a background service named gh-token-monitor via a plist daemon in macOS (~/Library/LaunchAgents/) or a systemd unit in Linux to intercept newly generated session tokens Microsoft Threat Intelligence.
  5. Dead-Man Switch / Anti-Analysis Wipe: If the payload detects a sandbox environment (e.g., standard VM analysis indicators) or if a query to its C2 reveals that the stolen publishing token has been revoked, it launches a destructive system command (rm -rf /*) to destroy evidence and disrupt incident response Microsoft Threat Intelligence.

Exfiltration / C2

domains:
  - "filev2.getsession[.]org"
  - "api.masscan[.]cloud"
  - "git-tanstack[.]com"
  - "t.m-kosche[.]com"
ips:
  - "N/A"
urls:
  - "https://filev2.getsession[.]org/upload"
  - "https://api.masscan[.]cloud/ping"
protocols:
  - "HTTPS"
  - "DNS"
endpoints:
  - "/upload"
  - "/ping"
confidence: high

Propagation

The worm is self-propagating Tenable. Upon harvesting npm and PyPI publishing tokens from compromised workstations or CI runners, it sends them back to the C2 or uses them locally to identify other repositories accessible to that developer Tenable. The malware automatically modifies those downstream packages, signs them, and publishes infected versions to the registry under the developer’s identity, continuing its exponential spread across the supply chain Tenable.

Obfuscation or Evasion

In addition to Bun runtime smuggling, the worm hides its payload using complex XOR obfuscation and packs its Python components into a zipapp (transformers.pyz) Endor Labs. The use of forged Sigstore certificates allows it to bypass cryptographic strictness policies that require verified build provenance Wiz.io.

Affected Assets and Blast Radius

affected_assets:
  ecosystems:
    - "npm"
    - "PyPI"
  packages:
    - "@tanstack/router"
    - "@tanstack/react-query"
    - "@tanstack/store"
    - "@antv/g2"
    - "@antv/g6"
    - "@sap/cds"
    - "@sap/cds-dk"
    - "opensearch-py"
    - "lite-llm"
    - "nx-console"
  versions:
    - "@tanstack/* published on May 11, 2026"
    - "nx-console@18.95.0"
  repositories:
    - "github.com/TanStack/router"
    - "github.com/antvis/*"
    - "github.com/nrwl/nx-console"
  container_images:
    - "N/A"
  CI_CD_systems:
    - "GitHub Actions"
  developer_tools:
    - "VS Code"
    - "Claude Code"
  environments:
    - developer workstations
    - CI runners
    - build pipelines
    - containers
    - production systems

credentials_at_risk:
  - npm tokens
  - GitHub tokens
  - cloud credentials
  - SSH keys
  - environment variables

not_currently_known_to_affect:
  - Non-NodeJS/Non-Python development environments lacking Bun and Python command-line tools.

Indicators of Compromise

domains:
  - value: filev2.getsession[.]org
    source: https://www.endorlabs.com/blog/mini-shai-hulud-npm-worm-hits-sap-developer-packages
    confidence: high
  - value: api.masscan[.]cloud
    source: https://www.endorlabs.com/blog/mini-shai-hulud-npm-worm-hits-sap-developer-packages
    confidence: high
  - value: git-tanstack[.]com
    source: https://tanstack.com/blog/postmortem-cve-2026-45321
    confidence: high
  - value: t.m-kosche[.]com
    source: https://www.endorlabs.com/blog/mini-shai-hulud-npm-worm-hits-sap-developer-packages
    confidence: high
ips: []
urls:
  - value: https://filev2.getsession[.]org/upload
    source: https://www.endorlabs.com/blog/mini-shai-hulud-npm-worm-hits-sap-developer-packages
    confidence: high
  - value: https://api.masscan[.]cloud/ping
    source: https://www.endorlabs.com/blog/mini-shai-hulud-npm-worm-hits-sap-developer-packages
    confidence: high
hashes:
  - value: ab4fcadaec49c03278063dd269ea5eef82d24f2124a8e15d7b90f2fa8601266c
    source: https://www.endorlabs.com/blog/mini-shai-hulud-npm-worm-hits-sap-developer-packages
    confidence: high
files:
  - value: router_init.js
    source: https://tanstack.com/blog/postmortem-cve-2026-45321
    confidence: high
  - value: setup_bun.js
    source: https://www.endorlabs.com/blog/mini-shai-hulud-npm-worm-hits-sap-developer-packages
    confidence: high
  - value: bun_environment.js
    source: https://www.endorlabs.com/blog/mini-shai-hulud-npm-worm-hits-sap-developer-packages
    confidence: high
  - value: transformers.pyz
    source: https://www.endorlabs.com/blog/mini-shai-hulud-npm-worm-hits-sap-developer-packages
    confidence: high
  - value: gh-token-monitor
    source: https://www.microsoft.com/en-us/security/blog/hunting-the-shai-hulud-supply-chain-worm
    confidence: high
package_versions:
  - value: nx-console@18.95.0
    source: https://www.sentinelone.com/blog/anatomy-of-cve-2026-45321
    confidence: high

Detection and Hunting

hunt_queries:
  dependency_lockfiles:
    - "nx-console@18.95.0"
  files:
    - "router_init.js"
    - "setup_bun.js"
    - "bun_environment.js"
    - "transformers.pyz"
    - "gh-token-monitor"
  network:
    - "filev2.getsession[.]org"
    - "api.masscan[.]cloud"
    - "git-tanstack[.]com"
    - "t.m-kosche[.]com"
  ci_cd_checks:
    - "Audit GitHub Actions cache configurations to ensure fork workflows do not share write-access to the cache of main branch workflows."
    - "Audit repository pull_request_target workflows; ensure they do not check out and run untrusted code from fork pull requests directly."
  endpoint_checks:
    - "Scan developer workstations for macOS LaunchAgents located at ~/Library/LaunchAgents/com.gh.token.monitor.plist"
    - "Check developer systems for systemd units matching gh-token-monitor.service"
    - "Audit .vscode/tasks.json and local .claude/settings.json directory structure for modifications"

Remediation Workflow

  • Immediate:
    1. WARNING: Do not revoke tokens before checking for persistence hooks. If the malware’s dead-man switch detects that its active tokens have been revoked, it may trigger a destructive home directory wipe (rm -rf /*). First, check and terminate any active gh-token-monitor daemon or malicious VS Code task runners Microsoft Threat Intelligence.
    2. Revoke and rotate ALL AWS keys, GCP keys, Azure credentials, Kubernetes secrets, .npmrc registry publishing tokens, GitHub PATs, and SSH keys that were exposed on the developer’s workstation or CI runners Endor Labs.
    3. Remove affected versions of packages from lockfiles and clear the registry cache TanStack Blog.
  • Short-term: 4. Terminate and re-provision affected CI/CD runner host machines or VMs to clear hidden memory or cache poisoning traces SentinelOne. 5. Clean out local developer directories: remove .vscode/tasks.json injected blocks, delete local .claude folders, and verify launch agents Microsoft Threat Intelligence.
  • Long-term: 6. Configure the package manager to ignore lifecycle scripts globally:
    npm config set ignore-scripts true
    1. Restrict and audit pull_request_target usage in all repositories. Avoid sharing build cache write privileges between pull request contexts SentinelOne.

Defensive Lessons

  • prevent: Restrict GitHub Actions workflows from executing user-submitted code in trusted contexts. Use isolated cache policies to prevent cache poisoning, and avoid pull_request_target triggers where possible.
  • detect: Monitor for anomalous binary downloads (like the Bun runtime) during package dependency resolution, and alert on any developer workstation writing to system services or daemon folders during npm installations.
  • respond: Isolate the target workstation before performing credential revocation to prevent automated dead-man switches from executing destructive filesystem wiping commands.

Open Questions

  • What other package registries or enterprise ecosystems have been targeted by TeamPCP using this specific self-propagating worm?
  • How many developer machines were wiped as a result of the dead-man switch command before responders understood the revocation trigger?

Sources

  1. TanStack Blog. Role: DIRECT_SOURCE Impact: Detailed explanation of the TanStack compromise, the exact exposure window (19:20 - 19:26 UTC), affected packages, and the OIDC exploitation chain.
  2. SentinelOne. Role: PRIMARY_RESEARCH Impact: Deep technical walkthrough of the cache-poisoning exploit, the pull_request_target misconfiguration, and downstream Nx Console compromise.
  3. Endor Labs. Role: PRIMARY_RESEARCH Impact: Initial discovery of the worm’s SAP CAP targets, Bun runtime smuggling, and Python transformers.pyz payload.
  4. Wiz.io. Role: PRIMARY_RESEARCH Impact: Analysis of the Sigstore SLSA Build Level 3 provenance forgery and the federation bypass.
  5. Tenable. Role: SECONDARY_ANALYSIS Impact: Discussion of TeamPCP’s Dune-themed indicators, exfiltration repositories, and worm-like lateral movement.
  6. Microsoft Threat Intelligence. Role: PRIMARY_RESEARCH Impact: Identification of the persistent IDE task hooks, macOS/Linux LaunchAgent services, and the credential revocation dead-man switch behavior.
  7. Aikido Security. Role: SECONDARY_ANALYSIS Impact: Overall synthesis of the massive May 2026 supply chain wave and remediation recommendations.