Popular npm Packages in the keyv and Cacheable Namespaces Compromised in Active Supply Chain Attack

Popular npm Packages in the keyv and Cacheable Namespaces Compromised in Active Supply Chain Attack
Socket is tracking an active supply chain compromise in the keyv and cacheable npm ecosystems, where trojanized packages used a malicious preinstall hook to download Bun, steal cloud and CI credentials, and republish infected packages through stolen npm tokens. The campaign affected tens of millions of weekly downloads and also planted persistence in developer and AI coding environments via .claude and .vscode hooks. #keyv #cacheable #Jaredwray #Bun #npm #GitHubActions #HashiCorpVault

Keypoints

  • At least ten npm packages in the keyv and cacheable ecosystems were published with a malicious preinstall hook on August 4, 2026.
  • The compromised maintainer account “Jaredwray” was used to publish across multiple package families, including packages outside the original namespaces.
  • The malicious installer downloaded a standalone Bun runtime and executed a second-stage payload hidden in setup.mjs and Math_Symbol.js.
  • The payload harvested cloud, CI, GitHub, npm, Vault, and Kubernetes credentials, then used stolen tokens to self-propagate by republishing trojanized npm packages.
  • Stolen data was exfiltrated to threat actor GitHub repositories and DNS-resolved destinations, while autostart hooks were planted in .claude and .vscode.
  • A host-level dead-man’s switch was installed to watch for token revocation and execute a remote-supplied handler when the stolen GitHub token stopped working.
  • Socket detected [email protected] quickly after publication, but new malicious packages continued appearing in real time.

MITRE Techniques

  • [T1195.002] Compromise Software Supply Chain – The threat actor altered npm packages in the release process to distribute malicious code (‘published with a malicious preinstall hook’ and ‘republishes trojanized versions of other packages’).
  • [T1546.016] Installer Packages – The malware executed during installation through npm lifecycle scripts (‘preinstall’: ‘node setup.mjs’ and ‘delivered entirely through the npm lifecycle’).
  • [T1059.001] Command and Scripting Interpreter: JavaScript – The payload used Node.js and Bun scripts to run both stages (‘setup.mjs is a lightly obfuscated Node script’ and ‘execFileSync(bunBinary, [payloadPath])’).
  • [T1105] Ingress Tool Transfer – The loader downloaded a standalone Bun runtime from GitHub to execute the second stage (‘downloads a platform-matched standalone Bun runtime’).
  • [T1552] Unsecured Credentials – The payload searched for and collected cloud, CI, and developer secrets (‘harvests cloud and CI credentials’, ‘AWS/GCP/Azure keys’, ‘HashiCorp Vault tokens’, ‘Kubernetes service account tokens’, ‘npm tokens’).
  • [T1530] Data from Cloud Storage – The collector queried cloud instance metadata and credential sources from cloud environments (‘queries the AWS instance metadata service’ and reads ‘AWS credential chains and Secrets Manager’).
  • [T1213] Data from Information Repositories – It pulled secrets and tokens from GitHub and repository-related sources (‘enumerates GitHub Actions organization and repository secret metadata’ and commits stolen findings to GitHub repositories).
  • [T1027] Obfuscated Files or Information – Strings in the second stage were protected with polymorphic basE91 encoding (‘Strings are protected with polymorphic basE91 encoding’).
  • [T1071.001] Application Layer Protocol: Web Protocols – The malware used HTTPS, GitHub APIs, and npm registry endpoints for command, credential exchange, and publishing (‘downloads … over HTTPS’, ‘POST /user/repos’, ‘registry.npmjs.org/-/npm/v1/oidc/token/exchange/package/’).
  • [T1567.002] Exfiltration to Cloud Storage – Stolen data was sent to threat actor GitHub repositories (‘commits stolen findings using the GraphQL createCommitOnBranch mutation’).
  • [T1102.001] Web Service: Dead Drop Resolver – The DomainSender resolved destinations via DNS before sending data (‘resolves destinations via DNS and health-checks them before sending encrypted data’).
  • [T1547.001] Registry Run Keys / Startup Folder – Persistence was added through autostart hooks in repository and system startup locations (‘plants autostart hooks in .claude and .vscode’ and persists as a LaunchAgent or systemd user service).
  • [T1490] Inhibit System Recovery – The dead-man’s switch triggered destructive cleanup on token revocation, removing its own state and exiting (‘when the token stops working … it evaluates a remote-supplied handler string, then deletes its state and exits’).

Indicators of Compromise

  • [SHA-256] Malicious loader and payload files – 54dc7ea54a1317cca0e890a2770630cf7fa6c97813e0cb9d2caa93012b350668, 9fc2570b7cef51c1b8df116d144d11ff4096357be7d2c4c6367cfc2509cf1bcc
  • [SHA-256] Repository loader variant – fd3ca4007b225fdf8de7af4345a19179d5efa8c4bb9205f88cda806e5684b1eb, and one other file hash mentioned in the article
  • [SHA-512 tarball] Malicious npm package artifact – keyv-6.0.0.tgz / 37f9f847e9c3e520b47d83a9029e199dbc30c6a195a1d80467d0fb1a6fd5068728ad4d1a422995ca578359263afdac5d3b4fed7a6b9befad27de19cca6966952
  • [File names] Installer and payload files – setup.mjs, Math_Symbol.js, and math_init.js
  • [Network / IP] Cloud metadata service addresses used for credential theft – 169[.]254[.]169[.]254, 169[.]254[.]170[.]2
  • [Network / Domain / URL] Bun download and npm/GitHub endpoints – github[.]com/oven-sh/bun/releases/download/bun-v1.3.13/, registry[.]npmjs[.]org/-/whoami, registry[.]npmjs[.]org/-/npm/v1/oidc/token/exchange/package/
  • [Package names] Affected npm packages – [email protected], @cacheable/[email protected], [email protected], and other listed cacheable/keyv versions


Read more: https://socket.dev/blog/popular-npm-packages-in-the-keyv-and-cacheable-namespaces-compromised-in-active-supply-chain