August 5, 2026
The Shai-Hulud NPM Supply Chain Attack: Analysis and Indicators
Intro

By SOCFortress
3 min read
Intro
On August 4, 2026, the quiet, fundamental trust upon which the JavaScript ecosystem is built was shattered. Ubiquitous caching utilities like keyv and flat-cache—the "invisible plumbing" of modern development—were turned against the global developer community through a sudden, surgical maintainer account compromise. This wasn't a standard data leak; it was the activation of "Shai-Hulud," a predatory, self-replicating worm that is currently feasting on the secrets of the world's digital infrastructure.
A Reach Beyond Imagination (2 Billion and Counting)
The technical architecture of Shai-Hulud reveals a level of predatory sophistication rarely seen in the npm wild. By hijacking a maintainer with a portfolio of "boring" but essential caching utilities, the attackers achieved a reach that is mathematically staggering. The compromise didn't just hit obscure libraries; it struck the bedrock:
- keyv: 604 million monthly installs.
- flat-cache: 580 million monthly installs.
- file-entry-cache: 571 million monthly installs.
- cacheable-request: 137 million monthly installs.
What makes this particularly insidious is that these poisoned versions were published with valid provenance signatures from GitHub Actions. As a DevSecOps community, we've been told that "provenance" is our shield, but Shai-Hulud proves that when the identity behind the signature is compromised, the "Trust-by-Default" model becomes a suicide pact.
Update — August 5, 2026, 13:15 CEST: At least 444 packages (across 1381 versions) have been compromised by the worm, with a combined total of over 2 billion monthly installs at the time of writing.
The Bun Runtime as a Stealth Weapon
The attack uses a clever execution layer to stay under the radar: the Bun JavaScript runtime. The infection begins via the setup.mjs dropper, triggered by the preinstall hook—a persistent architectural weakness in npm that allows arbitrary code execution during a simple npm install.
Instead of relying on the host's Node.js environment, which is likely monitored by EDR and security sandboxes, setup.mjs silently pulls the Bun runtime (v1.3.13) directly from github.com/oven-sh/bun/releases/download/bun-v1.3.13/. It then uses Bun to execute the real teeth of the attack: a heavily obfuscated, 728 KB payload titled Math_Symbol.js. By introducing a secondary, independent runtime, the attackers effectively bypass traditional Node-based monitoring tools.
No Secret is Safe (From AWS to Slack)
The Shai-Hulud payload is a masterclass in secret harvesting, designed to strip a victim's environment of every conceivable credential. It doesn't just look for .env files; it performs a deep-memory raid.
Stolen Data Categories:
- Cloud & Infrastructure: Extracts AWS credentials from
~/.aws/, queries the EC2 Instance Metadata Service (targeting IMDSv2 with an IMDSv1 fallback), and enumerates entire AWS Secrets Manager vaults. - Containerization: Reads Kubernetes service account tokens, CA certificates, and namespace data to query the Kubernetes API directly.
- Enterprise Secrets: Uses a prioritized six-source hunt for HashiCorp Vault tokens, including Kubernetes auth logins and Vault's AWS IAM auth endpoints.
- Identity & Messaging: Aggressively scans for Stripe API keys and Slack tokens (
xox[baprs]-...).
Most alarmingly, the payload targets the GitHub Actions runner process memory directly. By dumping memory to steal ACTIONS_ID_TOKEN_REQUEST_TOKEN, the attackers can hijack OIDC tokens to facilitate further npm publishing. The scanner also leans into modern development trends by specifically targeting AI-assisted workflow configurations:
.claude/settings.json(Targeting Claude Code session secrets).vscode/tasks.json- KeePass databases (
*.kdbx) - Terraform state files and
.tfvars - VPN configurations (
*.ovpn)
Self-Replicating "Worm" Mechanism
Shai-Hulud is a true worm, leveraging stolen credentials to propagate across the ecosystem. It utilizes two primary vectors:
- NPM Tarball Infection: Using stolen npm tokens, the worm identifies every package the victim can publish, bumps the patch version (e.g., 1.2.3 to 1.2.4), and republishes the package with the
setup.mjsdropper and a community-spread variant of the payload calledmath_init.js. Because modern DevSecOps pipelines often use ^ or ~ inpackage.json, they automatically pull these malicious patches, turning CI/CD environments into infection factories. - GitHub Repository Infection: Using stolen GitHub App or PAT tokens, the worm commits malicious hooks into up to 50 branches per repository. These commits are authored by "claude" with the email
claude@users.noreply.github[.]comand the messagechore: update config, perfectly mimicking legitimate AI-generated maintenance.
Exfiltration Repository Description: "Shai-Hulud: Here We Go Again"
At the time of writing, roughly 1,300 public repositories matching this description have been identified, acting as drop points for encrypted credential bundles.
Blockchain-Backed Infrastructure Rotation
The attackers aren't just sophisticated; they are resilient. Shai-Hulud employs a "Web3" fallback mechanism to ensure its exfiltration remains active even if domains are seized. If the primary GitHub exfiltration fails, the payload queries an Ethereum smart contract (0xE1f2395ee43e45A1556EC6438a88c31B83493103) to retrieve the latest exfiltration domain.
The current fallback, npm-cache[.]com:443/router, was registered back in May 2026. This confirms that this wasn't a heat-of-the-moment exploit, but a long-con operation planned months in advance. By using a blockchain-based "router," the attackers can rotate their infrastructure without ever needing to update the code in the 444+ infected packages already in the wild.
Where Do We Go From Here?
The Shai-Hulud attack has proven that the "invisible" dependencies we ignore are the very places where our security is most brittle. Detection tools like Aikido, which flagged this as a 100/100 critical malware threat, and open-source projects like Safe Chain — which intercepts package commands to verify them against live threat intelligence — are no longer optional. They are the only way to break the preinstall hook's power.