Overview of the Keyv and Cacheable npm Supply-Chain Incident
A sophisticated supply-chain attack has impacted the JavaScript ecosystem after threat actors compromised the maintainer accounts for the widely used keyv and cacheable npm namespaces. According to analysis published in the SANS Internet Storm Center, the attackers published trojanized packages designed to harvest sensitive cloud credentials, environment secrets, and private keys.
Unlike traditional typosquatting campaigns, this incident operates as a worm. The malicious releases automatically leverage stolen npm authentication tokens to inject themselves into other packages managed by the compromised identity, recompute integrity hashes, and republish updated versions to the public registry.
Technical Analysis and Execution Vectors
The poisoned packages ship with a preinstall hook that executes setup.mjs. This script downloads a standalone Bun runtime, executes an obfuscated second-stage payload (Math_Symbol.js), and harvests available credentials, including:
- AWS instance metadata and cloud provider keys
- HashiCorp Vault tokens and Kubernetes service-account tokens
- GitHub Actions secrets and local npm tokens
- Arbitrary private keys and bearer tokens discovered via disk regex sweeps
IDE and AI Agent Execution Surfaces
Beyond standard installation vectors via npm install, the source repository included development environment autostart hooks. Specifically, a SessionStart entry in .claude/settings.json and a folderOpen task in .vscode/tasks.json execute the loader simply when the cloned folder is opened in an IDE or analyzed by an AI coding agent. This shifts the attack surface from active build pipelines to passive directory inspection.
The Dead-Man’s Switch Mechanism
A critical innovation in this campaign is the inclusion of a host-level dead-man’s switch. The payload establishes persistence as a macOS LaunchAgent or a Linux systemd user service disguised as a “GitHub Token Validity Monitor.” A watcher script polls the GitHub API every sixty seconds using a stolen token.
If the token returns an HTTP 4xx error—the exact response generated when an administrator revokes the credential—the monitor executes a remote-supplied handler string via eval, before self-clearing. Consequently, standard incident response reflexes like immediately revoking stolen tokens can inadvertently detonate the attacker’s secondary payload.
Actionable Mitigation and Incident Response Guidance
Defenders investigating potential exposure must alter their standard triage sequence to avoid triggering dormant host logic:
- Isolate First: Disconnect affected hosts from the network immediately. Network isolation prevents the watcher script from receiving an HTTP 4xx response, neutralizing the dead-man’s switch while halting data exfiltration.
- Preserve State: Do not power off compromised machines; retain volatile memory for forensic analysis.
- Inspect Development Workstations: Review environments for unauthorized persistence mechanisms, macOS LaunchAgents, systemd units, and unexpected entries in
.claude/or.vscode/configuration directories. - Rebuild Over Cleaning: Rebuild CI runners and host environments with confirmed execution rather than attempting manual cleanups, as arbitrary code execution leaves completeness guarantees out of reach.
Related: Fake Paysafe/Skrill SDKs on npm & PyPI Steal Credentials, Microsoft Exchange Zero-Day and npm Supply Chain Worm Under Active Use