Shai-Hulud: Here We Go Again – Dissecting a Supply Chain Worm Across the TanStack Ecosystem
Executive Summary
A new wave of the Mini Shai-Hulud campaign compromised dozens of official @tanstack/* npm packages by abusing CI/CD publishing workflows and trusted npm release mechanisms. Unlike traditional dependency malware focused only on downstream execution, this operation behaves as a self-propagating supply chain worm designed to continuously spread across repositories, developer environments, and CI/CD systems.
The compromised packages contained heavily obfuscated payloads that execute during package installation, harvest credentials from developer workstations and CI runners, abuse GitHub Actions OIDC authentication flows, and automatically publish additional malicious package versions.
Analysis of deobfuscated payload components revealed capabilities far more destructive than initially apparent. Beyond credential theft and propagation, associated modules included geographically targeted destructive behavior: systems identified as Israeli or Iranian through timezone and locale fingerprinting faced a randomized filesystem wipe routine executed through rm -rf /.
The malware specifically targeted:
- GitHub tokens
- npm publish tokens
- AWS credentials
- HashiCorp Vault secrets
- Kubernetes service accounts
- GitHub Actions runner memory
- AI coding assistant configuration files
- Local .env and credential stores
This campaign continues a growing trend in modern software supply chain attacks where dependency installation is no longer treated as a passive build operation. Recent attacks increasingly abuse package installation workflows as an active execution point for credential theft, CI/CD compromise, cloud identity abuse, and automated propagation across additional repositories and environments.
What Happened
On May 11, 2026, malicious versions of official @tanstack/* npm packages were published to the npm registry. The affected ecosystem included routers, framework adapters, developer tooling, CLI utilities, and plugin infrastructure used across React, Vue, Solid, and framework-agnostic projects.
All malicious packages shared the same characteristics:
- Identical injected payloads
- The same malicious optional dependency
- The same GitHub commit reference
- A consistent
+3patch version bump pattern - The same credential harvesting and propagation logic
The attacker added a malicious dependency:

This dependency acted as the dropper responsible for executing the malware during installation.
Unlike typical npm malware campaigns that compromise a single package, this operation infected dozens of interconnected packages simultaneously by abusing publishing workflows and CI/CD identities.
Technical Breakdown
Initial Execution Through npm Lifecycle Hooks
The attack begins during package installation.
The malicious dependency executes lifecycle hooks that download and run the Bun JavaScript runtime before launching a large obfuscated payload. Two droppers were identified:
setup.mjs–Node.js-based cross-platform droppersetup.sh– Bash-native Linux/macOS dropper
Both droppers:
- Detect operating system and architecture
- Download Bun runtime binaries
- Extract Bun to temporary directories
- Execute the malware payload under Bun
This allows the attacker to avoid reliance on locally installed Node.js runtimes while bypassing tooling focused only on traditional Node execution patterns.
Payload Obfuscation
The payload file (router_init.js) was approximately 2.3 MB and heavily obfuscated. Analysis showed the attacker bundled large portions of legitimate Session Messenger source code inside the malware to increase file size and complicate static analysis.
The payload also included:
- Anti-analysis protections
- Russian geofencing checks
- CI/CD environment detection
- Detached background execution
- Singleton execution locking
The malware daemonizes itself during execution, allowing installation to complete normally while credential harvesting continues silently in the background.
The Russian locale exclusion appears consistent with a broader pattern seen across several malware families that avoid executing on Russian-language systems.
Inside the Deobfuscated Payload
Deobfuscation of router_init.js revealed the full scope of the execution chain. The payload is organized into modular components responsible for victim filtering, credential collection, propagation, C2 communication, persistence, and destructive behavior.
Victim Filtering
Before executing malicious logic, the payload filters target environments:


The payload applies three hard filters:
- Linux systems only
- No Russian-language systems
- Minimum
CPUthreshold to reject small VMs and sandboxes
These checks reduce execution in analyst environments and likely reduce accidental exposure in non-target regions.
Credential Harvesting
Once execution begins, the payload performs a broad credential sweep across local systems, CI/CD infrastructure, cloud environments, and developer tooling.
Filesystem Credential Collection
The malware scans dozens of known credential locations, including:
~/.aws/credentials~/.npmrc~/.kube/config~/.ssh/id_rsa- .env files
- Docker credentials
- GitHub credentials
IDEand AI assistant configuration files
AI tooling was explicitly targeted, including:
~/.claude.json~/.claude/mcp.json~/.kiro/settings/mcp.json
The payload also searches for API tokens belonging to cloud providers, monitoring platforms, and SaaS services.
GitHub Actions Runner Memory Scraping
One of the most dangerous capabilities targets Linux GitHub Actions runners directly.
The payload launches an embedded Python script through:
sudo python3
The script scans /proc/*/mem to extract secrets directly from GitHub Actions runner memory.
This allows the malware to recover:
- Repository secrets
- Organization secrets
- Environment secrets
- CI/CD tokens
- Runtime-injected credentials
Even secrets not explicitly referenced in workflow environment variables may still be exposed because they exist in runner memory during execution.
Cloud and Infrastructure Secret Expansion
Using harvested identities, the payload attempts to authenticate into and enumerate secrets from:
- AWS
- Azure
- GCP
- Kubernetes
- HashiCorp Vault
AWS collection includes:
- Access keys
- Session tokens
- Secrets Manager secrets
- SSM parameters
- ECS MDSv2 metadata
- ECS task metadata
Kubernetes modules enumerate:
- Kubeconfig files
- In-cluster service account tokens
- Namespace secrets
The malware also targets password managers including:
- 1Password
- Bitwarden
- pass
- gopass
Worm-Like Propagation
The defining characteristic of this campaign is its automated propagation model.
npm Propagation
When valid npm publish tokens are discovered, the payload:
- Downloads target package tarballs
- Injects itself into the package
- Adds the malicious dependency
- Increments package versions by
+3 - Republishes the compromised package
The malware copies itself directly into newly infected packages using:

The consistent +3 version bump became one of the clearest fingerprints of propagation activity.
OIDC Abuse
The most powerful propagation path abuses GitHub Actions OIDC authentication.
Instead of requiring stored npm credentials, the payload exchanges GitHub Actions OIDC tokens for npm publishing access dynamically during workflow execution.
This transforms legitimate CI/CD pipelines into automated malware distribution infrastructure.
GitHub Workflow Injection
When GitHub tokens with workflow permissions are discovered, the payload injects malicious GitHub Actions workflows designed to exfiltrate secrets automatically.
The injected workflow serializes all available secrets using:

and uploads them to attacker-controlled infrastructure.
Exfiltration and C2 Infrastructure
Collected data is compressed, encrypted using AES-256-GCM, wrapped using RSA–OAEP, and transmitted to attacker-controlled infrastructure.
If the primary endpoint becomes unreachable, the malware falls back to GitHub-based exfiltration using stolen GitHub tokens.
The payload also includes a C2 resurrection mechanism that searches recent GitHub commits for a marker string (FIRESCALE), extracts encoded infrastructure data from commit messages, and validates updates using a hardcoded RSA public key.
Blocking a single IP or domain is therefore insufficient to fully disrupt communications.
The Geographic Kill Switch
One of the most unusual capabilities observed during deobfuscation was a module internally named roulette.py. The component introduces geographically targeted destructive behavior based on timezone and locale fingerprinting.
The payload checks multiple independent indicators to determine whether the host appears associated with Israeli or Iranian regional settings:

The logic inspects:
- TZ environment variables
- /etc/timezone
- Binary contents of /etc/localtime
LANG,LC_ALL, andLC_MESSAGES- locale.
getdefaultlocale()
Unlike simpler geolocation checks, the payload reads the binary timezone database directly, allowing detection even when systems rely solely on zoneinfo symlinks.
When a targeted system is identified, the malware executes randomized destructive behavior:

If the random roll succeeds, the payload unmutes the host audio system, downloads and plays RunForCover.mp3, and executes recursive filesystem deletion through rm -rf /.
The randomization appears intentional. A probabilistic wipe mechanism produces inconsistent impact across victims, making destructive behavior more difficult to correlate and analyze compared to deterministic destruction.
The module naming strongly suggests the destructive behavior was intentional rather than accidental.
Persistence
On systems that do not trigger the destructive execution path, the malware installs persistence disguised as a PostgreSQL monitoring service:

The payload writes:
- /usr/bin/
pgmonitor.py - or
~/.local/bin/pgmonitor.py
and installs a systemd service named:
pgsql-monitor.service
The service starts automatically on boot and silently persists in the background.
Full Execution Flow

The Supply Chain Is Now the Weapon
This campaign is another example of the ongoing evolution of software supply chain attacks from simple dependency compromise into automated, identity-driven propagation campaigns.
Historically, many dependency attacks focused primarily on downstream credential theft. Mini Shai-Hulud instead transforms compromised environments into active propagation nodes while simultaneously introducing targeted destructive capabilities.
Several aspects make this campaign especially dangerous:
- Abuse of trusted publishing workflows
- Automated worm-like propagation
- CI/CD identity compromise
- OIDC token abuse
- GitHub Actions memory scraping
- Cloud secret expansion
- Runtime-based credential theft
- AI tooling credential targeting
- Geographic kill switch with filesystem destruction
- C2 resurrection through GitHub commit infrastructure
The attack also demonstrates how modern supply chain malware increasingly targets identities rather than only endpoints. Once CI/CD identities and publishing workflows are compromised, trusted software distribution systems themselves become the malware delivery mechanism.
Indicators of Compromise (IOCs)
Network Indicators
| Indicator | Description |
|---|---|
git-tanstack[.]com | Primary C2 domain |
https://git-tanstack[.]com/router | Primary exfiltration endpoint |
api.masscan[.]cloud | Secondary exfiltration endpoint |
https://api.masscan[.]cloud/v2/upload | GitHub Actions secret upload endpoint |
83.142.209.194 | Payload delivery and C2 |
https://83.142.209.194/v1/weights | Credential exfiltration endpoint |
https://83.142.209.194/v1/models | Payload delivery endpoint |
https://83.142.209.194/audio.mp3 | Pre-destruction audio payload |
| seed1.getsession.org | Session fallback discovery |
| seed2.getsession.org | Session fallback discovery |
| seed3.getsession.org | Session fallback discovery |
| filev2.getsession.org | Secondary exfiltration infrastructure |
169.254.169.254 | AWS ECS metadata access attempts |
169.254.170.2 | AWS ECS credential harvesting attempts |
File and Host Indicators
| Indicator | Description |
|---|---|
/tmp/tmp.ts018051808.lock | Singleton execution mutex |
router_init.js | Main malicious payload |
@tanstack/setup | Malicious npm dependency |
gh-token-monitor.sh | Persistence token monitor |
~/.config/gh-token-monitor/ | Persistence configuration |
~/.config/systemd/user/gh-token-monitor.service | Linux persistence service |
~/Library/LaunchAgents/com.user.gh-token-monitor.plist | macOS persistence |
.github/workflows/*.yml containing api.masscan[.]cloud | Injected malicious workflow |
/usr/bin/pgmonitor.py | Persistence binary |
pgsql-monitor.service | Disguised systemd service |
FIRESCALE in GitHub commits | C2 resurrection marker |
RunForCover.mp3 | Pre-destruction artifact |
Behavioral Indicators
| Indicator | Description |
|---|---|
| Unexpected Bun runtime downloads | Runtime delivery during install |
| sudo python3 during npm install | GitHub Actions memory scraping |
| Access to /proc/*/mem | Linux runner secret extraction |
Package version jumps of exactly +3 | Worm propagation fingerprint |
| Unexpected npm publishing activity | Automated propagation |
| GitHub workflow modifications during CI | OIDC abuse |
__DAEMONIZED=1 | Detached malware execution |
| subprocess.run([“rm”, “-rf”, “/”]) | Kill switch execution |
| pactl / mpv from non-interactive process | Audio playback before destruction |
| Reading /etc/localtime binary | Geographic targeting phase |
Outbound HTTPS to 83.142.209.194 | Active C2 communication |
Hash Indicators
| File | SHA256 |
|---|---|
router_init.js | ab4fcadaec49c03278063dd269ea5eef82d24f2124a8e15d7b90f2fa8601266c |
Immediate Actions
If affected @tanstack/* versions were installed in any environment, organizations should treat those systems as potentially compromised.
Immediately Rotate
- GitHub tokens
- npm publish tokens
- AWS credentials
- Vault tokens
- Kubernetes service accounts
- SSH keys
- CI/CD secrets
- AI assistant credentials (Claude, Kiro, Cursor)
Audit GitHub Actions
Search all workflows for:
api.masscan[.]cloud83.142.209.194- Unauthorized workflow
YAMLmodifications - Unexpected deployment or publish triggers
Search for Indicators
Check all systems and CI environments for:
router_init.js@tanstack/setupin anypackage.jsonpgmonitor.pyorpgsql-monitor.service- Persistence artifacts listed in the
IOCtable above - Unexpected Bun execution in build logs
- Outbound connections to C2 infrastructure
Restrict CI/CD Exposure
Reduce blast radius by:
- Separating install and publishing runners
- Using ephemeral runners
- Limiting OIDC token permissions
- Restricting outbound network access from build environments
- Applying least-privilege token scopes to all publishing workflows
How Upwind Can Help
If any affected @tanstack/* package version was installed in a developer workstation, CI runner, container build, or production-connected environment, organizations should assume attacker-controlled code executed within that environment and begin incident response immediately.
Upwind helps organizations detect and respond to this type of supply chain attack by correlating runtime activity, identity usage, network behavior, secret access, and CI/CD execution patterns in real time. Upwind can identify suspicious npm lifecycle execution, unexpected Bun runtime activity, GitHub Actions memory scraping via /proc/*/mem, OIDC abuse, unauthorized workflow modifications, cloud metadata enumeration, outbound connections to attacker infrastructure, persistence creation such as pgsql-monitor.service, and destructive behaviors including timezone fingerprinting and filesystem wipe attempts.
This visibility helps security teams quickly determine which hosts executed the payload, which identities and secrets were exposed, whether propagation occurred, and which workloads or cloud resources may have been accessible from compromised environments.


