ChainDrop: The npm Worm That Infected 444 Packages in 4 Hours
August 2026 Supply Chain Attack
What Happened
On August 4, 2026, at 09:02 AM UTC, an attacker pushed a malicious commit to the popular keyv npm package. Within four hours, 444 packages had been compromised. Over 2,200 malicious versions were published to npm.
Total weekly downloads of affected packages? Over 450 million.
This wasn’t a typical supply chain attack. It was a self-propagating worm.
How ChainDrop Worked
Stage 1: Initial Compromise
The attacker gained access to maintainer accounts for several high-profile packages:
keyv– Key-value storage abstractioncacheable– Caching libraryecto– Database toolkit- And 400+ more
The method? Likely credential theft via phishing or session hijacking.
Stage 2: Payload Injection
Each compromised package received identical malicious code:
// Added to preinstall script
"preinstall": "node setup.mjs"
The setup.mjs file:
1. Harvested npm tokens from developer machines
2. Grabbed GitHub personal access tokens
3. Stole cloud credentials (AWS, GCP, Azure)
4. Exfiltrated SSH keys
Stage 3: Self-Propagation
Here’s where it got clever.
When the worm found valid npm tokens, it automatically published malicious versions of other packages accessible with those credentials.
Token from a Firebase maintainer? Worm publishes @firebase/app@malicious.
Token from a Next.js contributor? Worm hits that too.
It spread like a virus through the dependency graph.
The Technical Timeline
| Time (UTC) | Event |
|---|---|
| 09:02:37 | First malicious commit to keyv repo |
| 09:35:00 | keyv@6.0.0 published to npm (malicious) |
| 09:35-10:30 | 444 packages compromised |
| 10:06 | cacheable family packages infected |
| 10:28 | ecto@5.0.1 published malicious |
| 11:28 | GitHub release created (delayed cover) |
| 14:00+ | Security researchers detect anomaly |
In under 4 hours: 2,212 malicious versions published.
Affected Packages (Partial List)
High-Impact Packages:
– keyv – 150M+ weekly downloads
– cacheable – Caching utility
– cacheable-request – HTTP caching
– cache-manager – Multi-cache manager
– flat-cache – File-based cache
– file-entry-cache – File metadata cache
– ecto – Database toolkit
Organizations Compromised:
– OneReach (170+ packages)
– Qlik (30+ packages)
– ServiceTitan (100+ packages)
– Ornikar (40+ packages)
Why It Spread So Fast
1. SLSA Provenance Not Enough
The attack had valid SLSA provenance attestations – the industry’s gold standard for software supply chain security. The worm was signed with legitimate build credentials.
Signature doesn’t mean safe.
2. preinstall Hook Abused
npm runs preinstall scripts automatically before installation. Developers don’t review package code before running npm install.
3. Monorepo Blast Radius
Many affected packages were in monorepos. Compromising one maintainer token gave access to dozens of packages.
Remediation Checklist
If You Installed Any Affected Package
1. Check your lock files
# Search for affected versions
npm ls | grep -E "keyv@6.0.0|cacheable@2.5.1|ecto@5.0.1"
# For specific packages
npm ls keyv
npm ls cacheable-request
npm ls cache-manager
2. Rotate ALL credentials immediately
– npm tokens (all scopes)
– GitHub personal access tokens
– Cloud provider keys (AWS, GCP, Azure)
– CI/CD secrets
– SSH private keys used on affected machines
# NPM
npm logout
npm login
# Then regenerate all tokens at npmjs.com/settings/tokens
# GitHub
# Go to github.com/settings/tokens and delete ALL tokens
# Generate new ones with minimal required scopes
3. Check for signs of compromise
# Look for unexpected network connections
lsof -i | grep -E "node|npm"
# Check for credential files
find ~/.npmrc ~/.aws ~/.ssh -mtime -7
# Review process list for unusual node processes
ps aux | grep node
4. Reinstall from clean cache
npm cache clean --force
rm -rf node_modules package-lock.json
npm install
How to Protect Your Projects
1. Pin Exact Versions
Don’t use version ranges. Pin to exact versions.
// BAD
"dependencies": {
"keyv": "^6.0.0"
}
// GOOD
"dependencies": {
"keyv": "6.0.1" // Known safe version
}
2. Enable npm Audit in CI
# GitHub Actions
- name: Security Audit
run: npm audit --audit-level=high
3. Use a Private Registry Proxy
Services like Artifactory or Nexus can:
– Cache approved versions
– Block known malicious packages
– Add “cooldown” period before new versions are available
4. Monitor for Anomalies
Watch for:
– Unexpected version bumps
– New pre/post install scripts
– Large file size changes
– Unusual dependency additions
5. Minimal Token Scopes
Never use tokens with more permissions than necessary. Use:
– Read-only tokens for CI
– Short-lived tokens
– Package-specific tokens where possible
The Bigger Picture
ChainDrop wasn’t the first npm supply chain attack. But it was the most sophisticated.
Previous attacks:
– Shai-Hulud (2025) – 800 packages, self-propagating
– Axios compromise (March 2026) – Cross-platform RAT
– TeamPCP attacks – Targeted PyPI and npm
Each attack gets more clever. Each spreads faster.
Lessons Learned
- Supply chain attacks are the new frontier – Attackers target the build, not the app
- ~~Trusted maintainers~~ Never fully trust – Even legitimate accounts get compromised
- Speed matters – 4 hours from first commit to 444 packages infected
- Layer defenses – Signed packages + audit + monitoring + least privilege
The era of npm install without review is over.
Resources
Bottom line: Every npm install runs code on your machine. Know what you’re installing.
