OrbitalReg Sign in →

Supply-chain case study

Live · began 4 Aug 2026

The keyv npm worm: a live look at a self-propagating credential attack.

On 4 August 2026 a self-replicating worm tore through the npm keyv and cacheable ecosystem — hundreds of poisoned package versions, a preinstall script that harvests every credential it can reach, and a nastier twist than its predecessors: it plants persistence hooks in Claude Code and VS Code. This is happening now. Here is what it does, and — honestly — where a registry helps and where it doesn't.

If you install from npm, act first, read second. Treat any workstation or CI runner that ran an affected keyv/cacheable/cache-manager version since 4 Aug 2026 as credential-exposed. Pin exact versions from a known-good lockfile, and rotate GitHub, npm, cloud and SSH credentials — but remove the malware's credential-revocation watcher first (see mitigations below), or it fights your rotation.

What happened

A worm that steals keys and rewrites your IDE.

Starting with keyv@6.0.0, malicious releases carried a preinstall script that executes a ~727 KB compiled bundle — pulling down Bun 1.3.13 from GitHub if it isn't already present. The payload harvests GitHub, npm, cloud, HashiCorp Vault, Kubernetes, database and private-key material, and even reads GitHub Actions runner memory. It carries its own npm-publishing machinery, which is what makes it a worm: stolen npm tokens are immediately used to poison the next set of packages, autonomously.

The new twist is persistence through developer tooling. The malware writes a SessionStart hook into .claude/settings.json and an "Environment Setup" task with runOn: folderOpen into .vscode/tasks.json — so simply opening the repository later re-executes the payload. (VS Code blocks automatic tasks in untrusted workspaces and Claude Code applies workspace-trust protections, which blunts but does not erase this vector.) Exfiltration flows out through GitHub repositories created under the compromised identities.

Scale depends on who's counting, because tags are changing faster than trackers can freeze lists: SafeDep verified 353 poisoned versions across 79 names; Aikido's monitoring put it at 868+ packages across 1,381+ versions within hours. Analysts link it to the Shai-Hulud family from earlier in 2026. Initial access — how the first maintainer credential fell — is still unknown as of this writing.

Aug 4

2026, ~09:00 UTC — first malicious release (keyv@6.0.0)

79–868+

package names poisoned (SafeDep verified → Aikido monitoring)

~727 KB

compiled preinstall payload; harvests keys, reads CI runner memory

2

IDE persistence vectors — Claude Code + VS Code hooks

The OrbitalReg defence

What a curated registry actually changes.

Pinned, curated proxies

Developers and CI resolve against your OrbitalReg proxy, not npmjs directly. A version published minutes ago isn't served until it clears your remote-proxy policy — so a same-hour poisoned keyv release is not automatically reachable the instant it lands upstream.

Patch-version quarantine

Hold new upstream versions for N hours before serving them. This attack's whole advantage is speed; a quarantine window is the single control that most directly blunts a worm racing to propagate before advisories catch up.

Pull-gate on disclosure

Once the poisoned versions land in the OSV/advisory feeds, every pull of an affected version through your registry gets a 403 instead of the tarball — fleet-wide, from one policy change, without chasing each project's lockfile.

Audit trail + air-gap

The append-only trail answers "who pulled an affected version, when" in one query — the exposure list you need in the first hour of response. In air-gap mode, nothing new resolves at all until you explicitly import it.

The honest caveat — sharper than usual. A self-propagating credential worm is the case where a registry helps least at hour zero. Curated proxies and quarantine buy you time and a choke point; the pull-gate only bites once the bad versions are known. None of it protects a developer who installs from public npm directly, and none of it un-steals a credential already harvested by a preinstall script that ran before anyone knew. The registry shrinks the blast radius and speeds the response — it is not a force field. The controls that matter just as much here are npm 12+ (which blocks unapproved lifecycle scripts by default), lockfile pinning, and fast credential rotation.

Indicators of compromise

What to grep for right now.

IOCs as reported by Wiz, Socket, SafeDep and Aikido on 4 Aug 2026. This is a moving campaign — treat these as a starting point, not a complete list, and cross-check the live advisories below.

Live advisories & sources

Related analysis: a similar install-time attack hit the Cargo ecosystem weeks later — see the Rust crates backdoor, where malware ran during cargo build.

Exposed to this — or want to not be, next time?

Put a curated npm proxy between your builds and the next worm.

Rico, the founder, walks through a proxy + quarantine + pull-gate layout for npm and your other formats — and what the audit trail gives you in the first hour of an incident like this one.