
Inside the keyv npm Compromise: preinstall Malware, Trusted Provenance, and IDE Hooks
Snyk Security Research independently verified an active npm supply-chain compromise affecting keyv@6.0.0 and 10 related packages (cacheable family, ecto) published by maintainer jaredwray on August 4, 2026, adding a preinstall hook (setup.mjs) that loads a 727KB obfuscated second-stage payload (Math_Symbol.js) targeting GitHub/npm/cloud credentials, private keys, and Vault/Kubernetes tokens via a gh-token-monitor persistence mechanism. The attack also planted .claude/settings.json and .vscode/tasks.json hooks to trigger execution when developers open the repo in Claude Code or VS Code, and the malicious release was signed by a valid npm trusted-publisher (GitHub Actions) attestation, demonstrating that provenance can faithfully attest a build whose source was already compromised. Snyk provides byte-level tarball diffs, a minute-by-minute incident timeline, and remediation steps including pinning to keyv@5.6.0, hunting for gh-token-monitor persistence, and credential rotation.
What it is
An active npm supply-chain compromise of the jaredwray maintainer account, disclosed August 4, 2026. Snyk Security Research confirmed 11 malicious releases (not the "10 related" the summary implies) carrying identical payloads. Snyk advisory SNYK-JS-KEYV-18515941 classifies keyv@6.0.0 as embedded malicious code under CWE-506. No CVE or GHSA existed at research time.
Affected releases and rollback targets
All 11 carry a byte-identical setup.mjs (29,918 bytes) and Math_Symbol.js (727,680 bytes):
keyv@6.0.0@cacheable/net@2.1.1,@cacheable/node-cache@3.1.2,@cacheable/memory@2.2.1,@cacheable/utils@2.5.1cacheable@2.5.1,cacheable-request@13.0.20flat-cache@6.1.24,file-entry-cache@11.1.6cache-manager@7.2.10ecto@5.0.1
Known-good tags npm reverted to: flat-cache → 6.1.23, cacheable-request → 13.0.19, cache-manager → 7.2.9. ecto@5.0.1 matters for scoping — it was published at 10:28 UTC, after the first public warnings, so early lists omitting it are incomplete. At the 11:16 UTC snapshot, eight releases were still tagged latest; only those three had been removed.
How it detonates
preinstall runs automatically on dependency resolution — no import, app start, or API call needed. setup.mjs is an obfuscated loader; a cleaner copy committed under .claude/setup.mjs names Bun 1.3.13 and a second stage math_init.js. The loader fetches a Bun release from GitHub if Bun is absent, executes the 727KB stage via child_process.execFileSync, and cleans up temp artifacts. It runs platform recon on Linux/macOS/Windows with developer or CI-runner privileges. Every file under dist/ is identical to the 6.0.0-rc.1 candidate — the library works normally, which is deliberate concealment.
What to do
- Do not install the affected versions.
- Pin or downgrade to a last-known-good release. Note: no clean successor to
keyv@6.0.0had been published — pin below it. - Detect by hash and lifecycle behavior, not package name — the payload spans multiple packages and scopes.
- If a version ran: isolate the host, hunt and disable persistence, then rotate exposed credentials from a clean system.
- Check private mirrors and lockfiles even after npm removes a version — registry state changed during the incident, but cached copies persist.
Caveats
The page's malware analysis is cut off mid-sentence ("targets G…"), so the second stage's exact objective is unstated here. Snyk verified tarballs by SHA-256 without installing or executing the payload. Registry state was volatile — the removed/present split reflects one 11:16 UTC snapshot only.
Organisations named here
- Charlie Eriksen
- CWE-506
- gh-token-monitor
Technologies named here
- Snyk Security Research
- keyv
- SNYK-JS-KEYV-18515941
- npm registry search endpoint
- child_process.execFileSync
- @cacheable/net
- @cacheable/node-cache
- Bun runtime
- Snyk Learn lesson on compromised legitimate packages
- cacheable
- flat-cache
- Snyk npm security best practices
- @cacheable/memory
- cacheable-request
- file-entry-cache
- @cacheable/utils
- cache-manager
- ecto
- npm
- Bun
- VS Code
- Claude Code
- GitHub Actions
- Vault
Techniques named here
- Malicious npm preinstall lifecycle hook
- Obfuscated loader with staged payload
- Platform and runtime detection
- Credential and secret theft
- gh-token-monitor persistence
- IDE/dev-tool hook execution path
- Trusted publisher / provenance abuse
- Test-triggered payload execution in CI
- Verified commit from compromised identity
Threat actors named here
- gh-token-monitor
- Unidentified attacker behind keyv npm compromise
Related in Supply Chain


