Keyv-Linked npm Worm Poisons Hundreds of Packages, Plants Claude Code and VS Code Hooks
A credential-stealing npm worm originated in keyv@6.0.0 on August 4, 2026, spreading across hundreds of packages in the Keyv and Cacheable namespaces and beyond The attack used a preinstall script to execute a 727KB compiled payload that harvested credentials from GitHub, npm, cloud providers, Vault, Kubernetes, databases, and private keys, then propagated by poisoning additional packages The repository also planted Claude Code and VS Code hooks via .claude/settings.json and .vscode/tasks.json,
Analysis
TL;DR
- A credential-stealing npm worm originated in keyv@6.0.0 on August 4, 2026, spreading across hundreds of packages in the Keyv and Cacheable namespaces and beyond
- The attack used a preinstall script to execute a 727KB compiled payload that harvested credentials from GitHub, npm, cloud providers, Vault, Kubernetes, databases, and private keys, then propagated by poisoning additional packages
- The repository also planted Claude Code and VS Code hooks via .claude/settings.json and .vscode/tasks.json, creating secondary execution paths when users open the workspace
- The worm exploited legitimate CI/CD workflows to obtain valid OIDC and SLSA provenance attestations, making malicious releases appear trustworthy
- npm 12 blocks unapproved lifecycle scripts by default, but earlier versions and alternative install paths remain vulnerable; SafeDep verified 353 poisoned versions across 79 package names with broader estimates reaching 868 packages
Why It Matters
This incident demonstrates a sophisticated supply-chain attack that combines automated package poisoning with IDE-level persistence, showing how attackers can leverage legitimate build provenance to bypass trust mechanisms. For AI practitioners and security teams, it underscores the critical importance of verifying exact resolved dependency versions rather than relying on namespace-level blocklists, and highlights the growing risk of AI coding tools (Claude Code, VS Code) becoming additional attack vectors when workspace trust is misconfigured.
Technical Details
- Initial vector: keyv@6.0.0 added a
preinstallscript (node setup.mjs) that checked for Bun runtime, downloaded Bun 1.3.13 from official GitHub releases if absent, then executed a 727,680-byte compiled malicious bundle while leaving the legitimate library code unchanged - Payload capabilities: The bundle harvested GitHub tokens, npm credentials, cloud provider keys, HashiCorp Vault secrets, Kubernetes configs, database credentials, and private keys; it also read GitHub Actions runner memory, installed a token-revocation watcher (triggered on credential rotation to execute attacker handlers), and carried npm publishing machinery for autonomous propagation
- Secondary execution paths:
.claude/settings.jsoncontained aSessionStarthook calling.vscode/setup.mjs, and.vscode/tasks.jsonhad anEnvironment Setuptask withrunOn: folderOpencalling.claude/setup.mjs— both requiring workspace trust but executable in default configurations - Provenance exploitation: The malicious release passed through the project's legitimate GitHub Actions release workflow, obtaining valid OIDC and SLSA attestations that verified the build process but could not confirm source code integrity
- Scale and detection challenges: SafeDep verified 353 poisoned versions across 79 package names (442 versions/353 names wider); Aikido reported 868 packages/1,381 versions. The registry changed rapidly with earlier clean versions retagged as
latest, making static blocklists ineffective — exposure checks require exact package names, resolved versions, and lockfile analysis
Industry Insight
- Organizations should implement lockfile-pin verification and exact-version resolution checks in CI/CD pipelines rather than relying on namespace-level warnings; the rapid tag-churning in this campaign proves that cached or broad blocklists are insufficient against dynamic supply-chain attacks
- Security teams must audit Claude Code and VS Code workspace trust configurations immediately — the planted hooks demonstrate how AI-assisted development tools can become persistent execution channels even after the initial compromised dependency is removed; treat any workstation that ran an affected version as credential-exposed and remove the revocation watcher before rotating tokens
- The attack's use of legitimate SLSA/OIDC provenance to authenticate malicious releases signals a shift toward "trust-through-process" exploitation; software supply-chain security programs must evolve to verify source integrity at the commit level, not just attest to build reproducibility, and consider restricting lifecycle script execution by default even on npm < 12 environments
Disclaimer: The above content is generated by AI and is for reference only.