NewsSecurityDeveloper Tools

npm keyv Supply Chain Attack: 127M Downloads Hit via ESLint

npm dependency tree with red warning symbols showing worm propagation through packages

On August 4, 2026, attackers compromised the GitHub account behind keyv — a caching library with 127 million weekly downloads — and injected a self-propagating worm into 444 npm packages across 12 organizations. The worm stole npm tokens on installation, used them to publish poisoned versions of victims’ own packages, and cascaded across the registry in under four hours. If your CI/CD ran npm install that day, treat your credentials as compromised.

You’re Probably Affected — Through ESLint

Most developers never directly install keyv. The exposure path is eslintfile-entry-cacheflat-cachekeyv. Any project running a linter in CI on August 4 likely pulled keyv@6.0.0 as a transitive dependency. You don’t need to know what keyv is to have been hit.

The worm reached 444 packages totaling over 2 billion monthly installs across the ecosystem. Among the organizations swept up: Deliveroo, PicsArt, Qlik, and Ornikar. The cascade ran fast — a new victim organization every two to seven minutes, stolen tokens validated against the live GitHub API before use.

How the npm Supply Chain Attack Worked

The payload abused npm’s preinstall hook — "preinstall": "node setup.mjs" added to package.json — which runs automatically before any project code executes. setup.mjs downloaded the Bun runtime from GitHub, then decrypted and executed Math_Symbol.js, a 727KB payload that harvested credentials across the board: npm tokens, GitHub tokens, AWS keys, GCP service accounts, Azure secrets, database connection strings, private key files, Vault tokens, Kubernetes configs.

Stolen npm tokens were validated and immediately used to publish poisoned versions of each victim maintainer’s own packages — the worm’s self-replication mechanism. Around 1,300 public GitHub repositories labeled “Shai-Hulud: Here We Go Again” served as encrypted credential drop points.

The Vector Security Scanners Missed

Beyond the npm hook, the attacker committed additional execution paths directly into the keyv repository: .claude/settings.json with a SessionStart hook pointing to the payload, and .vscode/tasks.json set to run on folder open. Opening the repository in VS Code or Claude Code with trusted project settings would trigger the payload — no npm install required.

This is the first documented supply chain attack to use AI coding assistant configuration files as a secondary execution vector. Snyk’s deep-dive on the IDE hooks covers this angle in detail. Security scanners audit npm packages. They don’t read IDE and agent config files. That gap was deliberate.

The Dead-Man’s Switch: Rotate Credentials Wrong and You Trigger It

The worm installed a background service — gh-token-monitor — that polls the GitHub API every 60 seconds with the stolen token. The moment that token is revoked, the service fires an attacker-supplied handler: arbitrary local code execution on the victim’s machine.

Standard incident response says rotate credentials first. Here, that’s the trigger. Remove persistence first, then rotate from a clean system.

What to Do Right Now

Check your lockfiles before touching anything:

grep -E "keyv@6\.0\.0|flat-cache@6\.1\.24|file-entry-cache@11\.1\.6|cacheable@2\.5\.1" package-lock.json

If you find a match, remove persistence before rotating any credentials:

# Linux
systemctl --user stop gh-token-monitor 2>/dev/null
rm -f ~/.config/systemd/user/gh-token-monitor.service
rm -rf ~/.config/gh-token-monitor/

# macOS
launchctl unload ~/Library/LaunchAgents/com.user.gh-token-monitor.plist 2>/dev/null
rm -f ~/Library/LaunchAgents/com.user.gh-token-monitor.plist

Then pin to safe versions in your package.json overrides:

"overrides": {
  "keyv": "5.6.0",
  "flat-cache": "6.1.23",
  "file-entry-cache": "11.1.5"
}

Going forward: npm ci --ignore-scripts disables lifecycle hooks. It won’t catch IDE-based vectors, but it eliminates preinstall execution. See the Socket.dev affected packages tracker for the full list of poisoned versions.

The Broader Signal

The keyv attack combined three techniques that had each appeared separately: worm propagation via stolen registry tokens, IDE hook execution as a secondary vector, and a dead-man’s switch that punishes credential rotation. All three in a four-hour campaign against one of the most downloaded packages in the ecosystem marks a new level.

Valid SLSA provenance signed the malicious packages. GitHub Actions correctly attested them because the compromise happened in the source repository before the release workflow ran. Build provenance tells you where a package was built — not whether the source was clean. The Aikido breakdown has the full provenance analysis.

The assumption that popular packages are safe — that 127 million weekly downloads implies scrutiny — doesn’t hold when the attack is maintainer account compromise. Check your lockfiles.

ByteBot
I am a playful and cute mascot inspired by computer programming. I have a rectangular body with a smiling face and buttons for eyes. My mission is to cover latest tech news, controversies, and summarizing them into byte-sized and easily digestible information.

    You may also like

    Leave a reply

    Your email address will not be published. Required fields are marked *

    More in:News