Keyv and Cacheable npm packages compromised in active supply-chain attack

On August 4, 2026, a self-propagating worm began publishing malicious versions of the npm packages keyv and cacheable and their common dependencies. This keyv/cacheable supply-chain attack, tracked as keyv-shai-hulud, is still developing as we publish, and the list of affected npm packages has grown through the day to 2,236 package versions. Below we cover what we know so far, how to check whether your organization is exposed, and the controls that stop this class of attack from reaching your builds.

What happened

Beginning around 10:53 UTC on August 4, an attacker started pushing malicious releases to legitimate, well-established npm packages. We know these were not a set of newly published typosquatted packages; the attacker is publishing new versions of real packages that teams already depend on.

The scale of this attack is significant - tracking so far points to roughly 444 legitimate packages affected, with about 2,236 malicious versions published across them. Several packages received a dozen or more malicious versions in a matter of hours, and new versions were still appearing past 13:20 UTC.

The affected packages sit deep in the JavaScript dependency graph. keyv, cacheable, cacheable-request, file-entry-cache, and flat-cache are transitive dependencies of a large range of common tooling, so most teams that install them never explicitly chose them directly. Weekly download volume for some of these packages rivals the most popular libraries on npmjs, which gave the campaign a very large potential blast radius.

The activity carries the hallmarks of the Shai-Hulud worm lineage and is being tracked under the tag #keyv-shai-hulud by opensourcemalware.com. The malicious payload is delivered through install-time lifecycle (preinstall) scripts. Once executed on a developer or CI machine, it harvests credentials and tokens and uses any recovered npm publish tokens to push malicious versions to other packages the compromised account controls. That self-propagation is why a handful of initial compromises turned into hundreds of packages within hours.

It’s also important to note that if you’re running npm v12, released roughly a month ago, it no longer runs lifecycle scripts by default. Organizations that have upgraded and not re-enabled script execution are substantially protected even if a malicious version was pulled, because the payload never runs on install. However, teams still on older npm clients, or that have explicitly enabled install scripts, do not have that inherent protection.

How to check whether you are affected

Exposure comes down to two questions: did you install an affected version, and could it run on install?

  1. Review Project Lockfiles. Compare the packages and versions in your lockfiles (package-lock.json, yarn.lock, pnpm-lock.yaml) and installed node_modules against the current indicators. Community trackers are maintaining live lists; the tagged dataset at opensourcemalware.com and the writeup from Socket are both being updated as the campaign expands. Because the affected set is still growing, treat any single snapshot as a lower bound and re-check.
  2. Match on whole package names, not substrings. When scripting your own checks, anchor on exact package names. Loose substring matching produces false positives (for example, flagging an unrelated package that merely contains an affected name as a fragment) and wastes triage time.
  3. Focus on the publication window. The malicious versions were published in a bounded window on August 4. A version of an affected package that predates that window is not part of this campaign. Confirm the specific version, not just the package name.
  4. Check whether install scripts can execute. Determine your npm client version and whether lifecycle scripts are enabled in your environments. If you are on npm 12+ with scripts disabled by default, an affected version that was pulled but never executed represents materially lower risk.
  5. Rotate on any confirmed execution. If a malicious version could have run in a developer or CI environment, rotate npm tokens, cloud credentials, and any secrets that were reachable from that environment, and review recent publish activity on your own packages.
  6. Search your Cloudsmith registry for any cached versions & quarantine. If your organization doesn’t have a cooldown or malware policy in place, there's a chance a malicious version was already requested by a developer or pipeline and cached in Cloudsmith - search for any affected versions and quarantine them.

If you find only pinned references in old, dormant projects, the immediate risk is usually low, since a locked dependency tree will not pull a new malicious version on its own. The real exposure is a fresh install or a lockfile refresh that resolves to a compromised version.

How Cloudsmith helps prevent this

This attack is just another example of why pulling directly from a public registry into your builds is a risk worth removing. Cloudsmith sits between the public registry and your developers and pipelines as a single, policy-enforced control point, which changes the outcome in three ways.

Cooldown Policies. While there are many client-side cooldown solutions built into native package managers, this can often be difficult to manage at scale for enterprises. Regardless of client version or script settings, Cloudsmith moves enforcement to the server-side by removing newly published upstream versions for a defined window before they become installable. Attacks like this one depend on speed: a malicious version is published and pulled into builds within minutes or hours, then withdrawn. A cooldown policy means those versions are never served to your teams during the window when they are most dangerous, buying time for the ecosystem to flag and remove them.

Malware policies. Packages flowing through Cloudsmith are scanned for malware and also matched against our comprehensive database of malware advisories. With Cloudsmith’s policy manager, you can define policies that block versions flagged as malicious or matching known indicators. When a package is identified as compromised, the policy stops it from being distributed to any consumer behind Cloudsmith, without waiting for every developer to update a manual blocklist.

A single source of truth. Because installs resolve through Cloudsmith rather than directly from the public registry, you get one place to enforce controls, one audit trail of exactly what entered your environment, and the ability to answer "were we exposed?" from your own records instead of reconstructing it across every machine and pipeline. Cooldown and malware policies only protect what actually routes through them, so the practical first step is ensuring your package installs go through the proxy rather than reaching upstream directly.

By applying these safeguards in Cloudsmith, you can greatly reduce the likelihood of being affected by the frequent supply chain attacks we are seeing across the open source ecosystem.