mainkeyvkeyvcacheableThe initial seed included 11 packages across both namespaces: keyv, cacheable-request, cache-manager, @cacheable/utils, flat-cache, file-entry-cache, and others . Security researchers from Aikido Security, StepSecurity (which tracks the worm as "ChainDrop"), Socket, and Chainguard all independently confirmed the compromise within the first hours
.
Every poisoned package received the same infection pattern: two new files (setup.mjs and Math_Symbol.js) and a modified package.json with a "preinstall": "node setup.mjs".
When any developer or CI system ran npm installsetup.mjs dropper executed automatically before installation completed. Its job was to download a legitimate Bun JavaScript runtime binary from GitHub Releases, then launch the obfuscated second-stage payload (Math_Symbol.js, approximately 710–728 KB) .
Microsoft Threat Intelligence confirmed that the payload is a Mini Shai-Hulud variant . It harvests a wide range of credentials and secrets from infected environments
:
What made this attack particularly dangerous was its ability to self-propagate. After stealing npm publishing tokens and GitHub PATs from the infected environment, the worm used that access to publish additional malicious versions of other packages owned by different, unrelated maintainers .
The scope of the compromise expanded rapidly:
The worm crossed namespace boundaries — it did not stay within the keyv/cacheable family where it started. It jumped to packages owned by organizations including Deliveroo, Ornikar, OneReach, Picsart, Qlik, and ServiceTitan, among many others .
Stolen credentials were exfiltrated to a GitHub repository controlled by the attacker — the worm either created a new repository or used a dedicated exfiltration repo for this purpose . Multiple redundant exfiltration channels were built into the payload
, making it resilient to the takedown of any single channel.
Security researchers across multiple firms urged teams to treat any system that touched an affected package as fully compromised. The following remediation steps were consistently recommended :
Use npm/yarn/pnpm overrides (e.g., "overrides" in package.json) to prevent accidental reinstallation of poisoned versions . Check lockfiles (
package-lock.json, yarn.lock, pnpm-lock.yaml) for any affected package versions, including transitive dependencies .
Do not simply delete the malicious files from a machine that ran npm install. Assume that all secrets present on that host are compromised.
A critical detail: the malware sometimes sets up GitHub workflow watchers that can re-expose a new token the moment it is created . Researchers advised disabling or removing any monitoring service before rotating credentials
.
Clear npm/pnpm/yarn caches and Docker build caches on both developer machines and CI/CD runners . Rebuild all artifacts from scratch to prevent tainted dependencies from persisting in build caches or Docker layers
.
Search for newly created repositories or unauthorized workflows . Look for persistence artifacts such as
.claude/settings.json or .vscode/tasks.json that the worm may have created .
The Shai-Hulud worm attack of August 4, 2026 was a watershed moment for JavaScript ecosystem security. It demonstrated that a single compromised maintainer account — even without direct access to most of the affected packages — could cascade into a worm that poisoned well over a thousand packages within hours. The attack's use of a legitimate Bun runtime binary for payload execution, its self-propagation via stolen tokens, and its redundant exfiltration channels made it more sophisticated than previous supply chain attacks .
For engineering and security teams, the incident underscores the importance of pinning dependencies, disabling pre/post-install scripts where possible, monitoring for unusual GitHub activity, and maintaining incident response runbooks for supply chain compromises.