Shai-Hulud: npm Worm Infects keyv and Over 430 Packages

Step by step
How the Shai-Hulud attack unfolded
Click a phase for details – or let the animation play through.
PHASE 1/7 · Initial Access

Attackers hijacked the GitHub account of keyv maintainer Jared Wray and pushed a poisoned commit on August 4, 2026.

T1195.002 – Supply Chain Compromise: Compromise Software Supply Chain T1078 – Valid Accounts
  • Takeover of maintainer Jared Wray's account (keyv package)
  • First malicious commit at 09:02:37 in jaredwray/keyv (version 6.0.0)
  • keyv is downloaded ~127–153 million times per week
  • Injection of setup.mjs and Math_Symbol.js
PHASE 2/7 · Execution

During npm install the preinstall hook ran setup.mjs, downloaded the Bun runtime and executed obfuscated malware.

T1059.007 – Command and Scripting Interpreter: JavaScript T1204.003 – User Execution: Malicious Image
  • Abuse of the npm lifecycle script preinstall
  • setup.mjs downloads Bun runtime 1.3.13 from GitHub
  • Execution of 728 KB of obfuscated malware (Math_Symbol.js / math_init.js)
  • Valid SLSA provenance via GitHub Actions OIDC – checks rendered useless
PHASE 3/7 · Credential Collection

The credential stealer systematically searched the system for cloud, CI/CD and server credentials.

T1552.001 – Unsecured Credentials: Credentials In Files T1552.005 – Cloud Instance Metadata API T1528 – Steal Application Access Token
  • Cloud keys for AWS, GCP and Azure
  • HashiCorp Vault tokens and Kubernetes service accounts
  • GitHub and npm tokens as well as SSH keys
  • Encryption of stolen data with AES-256-GCM
PHASE 4/7 · Persistence

The malware embedded itself via IDE configuration files and protected itself with a dead man's switch.

T1546 – Event Triggered Execution T1554 – Compromise Host Software Binary
  • Hooks in .vscode/tasks.json and .claude/settings.json
  • Re-execution when the project is reopened
  • Dead man's switch monitors the stolen GitHub token
  • Revoking the token triggers a wipe function
PHASE 5/7 · Lateral Movement / Worm Propagation

Using stolen CI credentials the worm automatically copied itself onto hundreds of additional packages.

T1195.002 – Supply Chain Compromise: Compromise Software Supply Chain T1078 – Valid Accounts
  • Second wave began at 09:38:13 with @thiennq/docs-viewer@1.6.2
  • Infection of the cacheable namespace (flat-cache@6.1.24, file-entry-cache@11.1.6)
  • Over 433 packages in 2,201 versions affected by 13:20
  • Spread across more than 14 organizations (e.g. @servicetitan, @onereach, @qlik)
PHASE 6/7 · Exfiltration

The encrypted credentials were exfiltrated via GitHub repositories and dynamically distributed control servers.

T1567 – Exfiltration Over Web Service T1567.001 – Exfiltration to Code Repository
  • New GitHub repos titled 'Shai-Hulud: Here We Go Again'
  • Rotating C2 servers addressed via an Ethereum smart contract
  • Encryption with an operator-provided RSA key
  • Data secured with AES-256-GCM
PHASE 7/7 · Impact

Over 2 billion monthly downloads were affected, with potential access to production systems and customer data.

T1195.002 – Supply Chain Compromise: Compromise Software Supply Chain
  • Over 440 compromised packages across more than 2,200 versions
  • More than 2 billion monthly downloads affected
  • Stolen cloud and CI/CD credentials enable production access
  • GDPR notification duty (Art. 33/34) possible due to credential theft
Short & clear answers
Frequently asked questions about this incident
Am I affected by the Shai-Hulud npm attack?
Anyone who installed or updated one of the infected package versions between the morning of August 4, 2026 and npm's cleanup is affected. Check your lock files (package-lock.json, yarn.lock or pnpm-lock.yaml) for affected versions such as keyv 6.0.0, flat-cache 6.1.24 or file-entry-cache 11.1.6. Since flat-cache and file-entry-cache are deep transitive dependencies, they are hidden in almost every Node.js project.
How do I check whether my project is infected?
Open your lock file and search for the affected versions (e.g. keyv 6.0.0, flat-cache 6.1.24, file-entry-cache 11.1.6). Then search your project directory for the malicious files setup.mjs, Math_Symbol.js or math_init.js. Also check for unexpected .vscode/tasks.json or .claude/settings.json files that contain a call to setup.mjs.
What do I need to do right now if I'm affected?
First, isolate potentially affected systems (developer machines and CI/CD runners) from the network. Then remove the dead-man's switch (e.g. ~/.local/bin/gh-token-monitor.sh) BEFORE revoking any credentials, otherwise a deletion routine may be triggered. Only after that should you rotate all credentials (npm, GitHub, AWS, GCP, Azure, Kubernetes, Vault) and downgrade the affected packages to their previous clean versions.
Why didn't the security checks detect the attack?
The attackers hijacked the projects' real, official release automation, so every poisoned package carried a valid SLSA provenance signed by GitHub Actions. This provenance only proves which repository a package was built from – it says nothing about the package's actual contents. According to StepSecurity, any tooling that only gates on valid provenance would have waved keyv@6.0.0 straight through.
Am I affected if I don't code myself but an agency runs my website?
Many web projects rely on Node.js behind the scenes and therefore potentially on exactly these packages. Ask your service provider or agency immediately whether and how they are affected. Since the malware steals cloud keys and database credentials, GDPR (Art. 33) may require you to notify the supervisory authority within 72 hours if customer data is at risk.
More security news
You might also be interested in
Critical Elementor Pro Flaw: Attackers Can Fully Take Over WordPress Sites
A file upload bug in Elementor Pro up to 4.2.1 allows RCE without login. Version 4.2.2 fixes the flaw – update now!
Pods Plugin: Critical Flaw Enables Admin Takeover, No Login
A critical flaw in the WordPress plugin Pods lets attackers overwrite admin passwords without login. Over 100,000 sites are affected.
miniOrange SAML SSO: Critical Bypass Turns Attackers Into Admins
Two critical auth bypasses in the miniOrange SAML SSO plugin allow forged SAML assertions—up to full WordPress admin access.