# ChainDrop/Mini Shai-Hulud npm Worm Compromises keyv, cacheable, and 400+ Downstream Packages via Ethereum-Resolved C2

> On August 4, 2026, attackers compromised the GitHub account of the keyv/cacheable maintainer and published trojanized releases (keyv@6.0.0 and nine sibling packages) carrying a preinstall-hook dropper that fetches the Bun runtime and runs a 727,680-byte obfuscated credential-stealing payload, self-propagating to 1,300+ package versions with combined downloads exceeding 1.3-2 billion/month. The worm, dubbed ChainDrop, is the latest wave of the Shai-Hulud/"Mini Shai-Hulud" campaign lineage and resolves its C2 endpoint dynamically via an Ethereum smart-contract call, evading static domain/hash-based detection.

- **Published:** 2026-09-01T00:00:00Z
- **Last reviewed:** 2026-09-01T00:00:00Z
- **Canonical:** https://intel.threadlinqs.com/threat/TL-2026-2285
- **ID:** TL-2026-2285
- **Severity:** CRITICAL
- **Category:** SUPPLY_CHAIN
- **Status:** ACTIVE
- **Actor:** TeamPCP
- **Detections:** 9 · **IOCs:** 29 (full data via the Threadlinqs MCP server — Purple tier)

## Description

At approximately 09:00 UTC on August 4, 2026, a threat actor compromised the GitHub account of jaredwray, maintainer of the widely-used keyv (600M+ monthly downloads) and cacheable npm namespaces, and pushed malicious commits directly to the keyv repository's main branch. Within minutes the actor published keyv@6.0.0 along with malicious versions of cacheable-request@13.0.20, cache-manager@7.2.10, @cacheable/utils@2.5.1, flat-cache@6.1.24, and at least five other packages in the same namespaces.

Each trojanized release added a `"preinstall": "node setup.mjs"` entry to package.json. setup.mjs is a base64/RC4-obfuscated stager using control-flow flattening that checks for and downloads the Bun JavaScript runtime v1.3.13 directly from Bun's official GitHub releases (not attacker infrastructure) into a /tmp/bun-dl-*/ staging directory, then hands execution to a 727,680-byte compiled Bun CommonJS bundle named Math_Symbol.js (worm-propagation builds use the filename math_init.js). Running the payload under Bun rather than Node.js gives the malware a current, predictable execution environment regardless of the victim's installed Node version and avoids Node-focused EDR heuristics.

The payload's credential-harvesting component ("collector") scans for npm tokens (.npmrc), GitHub personal-access/session/OIDC tokens (including GitHub Actions ACTIONS_ID_TOKEN_REQUEST_TOKEN/URL), AWS IAM role credentials and Secrets Manager/SSM Parameter Store secrets, GCP/Azure/Alibaba/Tencent cloud credentials, HashiCorp Vault tokens, Kubernetes service-account tokens, database connection strings, CI/CD secrets (Jenkins master.key, Argo CD, Harbor), AI-tooling credentials (Anthropic/Claude, OpenAI, Cursor, Gemini), and cryptocurrency wallets (Foundry, Solana, Monero). Stolen tokens are pre-validated in real time against registry.npmjs.org/-/whoami before exfiltration. Harvested data is gzip-compressed, encrypted with a randomly generated AES-256-GCM key, and that key is itself RSA-encrypted under an attacker-controlled public key before exfiltration.

Rather than hardcoding a C2 domain, the malware queries an Ethereum smart contract (StringListStore, address 0xE1f2395ee43e45A1556EC6438a88c31B83493103) via eth_call through legitimate public RPC endpoints (eth-mainnet.nodereal.io, go.getblock.io, eth.llamarpc.com) to retrieve the current exfiltration endpoint at runtime, blending C2 lookups into normal blockchain-developer network traffic. Observed resolved/fallback exfiltration and staging domains include npm-cache.com, pypi-get.com, js-mirror.com, and the DGA-style awqhnjewqjkl.icu. When smart-contract resolution or direct exfiltration fails, the malware falls back to creating public GitHub repositories under compromised identities (546 identified, description "Shai-Hulud: Here We Go Again", containing a results/ directory) as a dead-drop; per one vendor's analysis the only hosts strictly required for this fallback path are github.com, api.github.com, and registry.npmjs.org, since stolen GitHub tokens alone are sufficient to create repositories and exfiltrate via the authenticated-user API.

Self-propagation logic identifies npm accounts/tokens with publish permission and bypass_2fa enabled reachable from harvested credentials, downloads the latest tarballs of every package the compromised identity maintains, injects the same preinstall hook plus setup.mjs/Math_Symbol.js (or setup_bun.js/bun_environment.js in the related Shai-Hulud "Second Coming"/V2 lineage), and republishes trojanized versions signed under the victim's legitimate identity. Because the republished packages pass through real GitHub Actions build pipelines, they carry valid OpenID Connect and SLSA provenance and Sigstore/Rekor-signed attestations with a green GitHub-verified badge (commit author github-actions[bot]) — the build process is faithfully attested, but the attestation cannot establish that the source entering the pipeline was safe, defeating provenance-based trust checks. Separately, the compromised keyv/cacheable repositories carried IDE-triggered persistence artifacts (.claude/settings.json SessionStart hook calling .vscode/setup.mjs, and .vscode/tasks.json "Environment Setup" task with runOn: folderOpen calling .claude/setup.mjs) that could execute the payload chain merely by opening the cloned repository in VS Code or Claude Code, independent of npm install — both editors' workspace-trust prompts are the only barrier to automatic execution.

By public tracking, 868 packages across 1,381 versions were confirmed poisoned by 13:37 CEST on August 4; later counts rose to 1,684 poisoned versions across 420 package names tied to nine npm organizations (including the @ornikar and @qlik scopes), with combined monthly installs exceeding 1.3–2 billion. npm restored clean prior versions (keyv@5.6.0, flat-cache@6.1.23, cache-manager@7.2.9, cacheable-request@13.0.19) as the `latest` dist-tag later the same day; keyv@6.0.0 itself was pulled from the registry entirely, so lockfiles pinned to it now fail to resolve.

Security researchers link the malware family, filenames, and Bun 1.3.13 toolkit to a broader 2026 campaign lineage attributed with low confidence to the group tracked as TeamPCP (historically also tracked as TA-NATALSTATUS/IronErn): an April 2026 PyTorch Lightning PyPI compromise and a May 2026 @antv npm ecosystem compromise used the identical setup.mjs/Bun 1.3.13 toolkit. Two individuals (Louis Michael Gaebler, 23, and Ruben Ian Thomson, 21) were charged in Perth, Australia on August 27, 2026 with 14 offences tied to a March 2026 TeamPCP supply-chain compromise of Trivy, Checkmarx KICS, and LiteLLM using overlapping infrastructure and staging techniques — but investigators explicitly note the self-identifying markers needed to formally tie this specific keyv/cacheable/ChainDrop incident to a named actor were not recovered, so attribution to TeamPCP for this wave remains unconfirmed.

The incident is the latest in the Shai-Hulud worm lineage: the original Shai-Hulud campaign (detected September 2025) compromised 500+ packages via stolen maintainer tokens and used randomized/generic repository names to evade infrastructure-pattern detection; a second wave ("The Second Coming"/Shai-Hulud V2, detected November 24, 2025) added Bun-runtime loading via setup_bun.js/bun_environment.js (a 480,000+ line obfuscated payload), TruffleHog-based secret scanning, GitHub Actions self-hosted-runner persistence (registered as "SHA1HULUD"), and destructive wiper fallback behavior against the victim's home directory when propagation/exfiltration fails. No CVE or GHSA identifier had been assigned to the keyv/cacheable/ChainDrop compromise at time of research; Snyk tracks it as SNYK-JS-KEYV-18515941 (CWE-506, Embedded Malicious Code) and Mend.io as advisory MSC-2026-6430. Singapore's CSA issued advisory AD-2026-009 covering the ongoing campaign.

The broader ecosystem response accelerated adoption of npm Trusted Publishing (OIDC-based, tokenless package publishing that eliminates long-lived npm tokens as a theft target): weekly Trusted Publishing adoption jumped to roughly 430 packages, and cumulative adoption grew 3.4x over 18 months, driven by Shai-Hulud and at least 14 related supply-chain incidents including this one. Detection-methodology analysis of this and the Shai-Hulud incidents (the hunt source for this record) argues that hash- and named-indicator detection (the base of the Pyramid of Pain) catches only already-known artifacts, while durable detection requires behavioral/TTP-level rules on the shape of the attack — preinstall-script network egress, unexpected runtime downloads (Bun fetched by a package that has no reason to need it), and credential-file access patterns — rather than rotating IOCs.

## MITRE ATT&CK

- T1588 Obtain Capabilities
- T1584 Compromise Infrastructure
- T1195 Supply Chain Compromise
- T1078 Valid Accounts
- T1059 Command and Scripting Interpreter
- T1550 Use Alternate Authentication Material
- T1027 Obfuscated Files or Information
- T1553 Subvert Trust Controls
- T1552 Unsecured Credentials
- T1528 Steal Application Access Token
- T1087 Account Discovery
- T1005 Data from Local System
- T1560 Archive Collected Data
- T1573 Encrypted Channel
- T1567 Exfiltration Over Web Service

## Sources

- [The dark figure of supply chain detection](https://www.aikido.dev/blog/dark-figure-supply-chain-detection)
- [The keyv and cacheable npm Supply Chain Attack: Inside the Mini Shai-Hulud Campaign](https://www.chainguard.dev/unchained/the-keyv-and-cacheable-npm-supply-chain-attack-inside-the-mini-shai-hulud-campaign)
- [keyv and cacheable compromise](https://socket.dev/supply-chain-attacks/keyv-and-cacheable-compromise)
- [keyv and cacheable npm Package Hijacked in Supply Chain Attack](https://www.wiz.io/blog/keyv-and-cacheable-npm-supply-chain-attack)
- [Malicious keyv Package on npm Steals CI Secrets via GitHub](https://www.mend.io/blog/keyv-malicious-packages/)
- [Shai-Hulud/CHAINDROP npm Supply Chain Worm](https://www.elastic.co/security-labs/shai-hulud-chaindrop-npm-supply-chain)
- [Keyv-Linked npm Worm Poisons Hundreds of Packages, Plants Claude Code and VS Code Hooks](https://thehackernews.com/2026/08/keyv-linked-npm-worm-poisons-hundreds.html)
- [Alleged TeamPCP Hackers Charged in Australia Over Major Supply Chain Attacks](https://thehackernews.com/2026/08/alleged-teampcp-hackers-charged-in.html)
- [Inside the keyv npm Supply Chain Compromise](https://snyk.io/blog/inside-keyv-npm-compromise-preinstall-malware-trusted-provenance-ide-hooks/)
- [Ongoing npm Supply Chain Attack Affecting Keyv and Related Packages (AD-2026-009)](https://www.csa.gov.sg/alerts-and-advisories/advisories/ad-2026-009/)
- [Shai-Hulud was the best thing to happen to supply chain security](https://www.aikido.dev/blog/shai-hulud-trusted-publishing)

## Full data

Detection queries (Splunk SPL / Microsoft KQL / Sigma) and IOC values require the Threadlinqs MCP server (Purple tier): https://intel.threadlinqs.com/mcp

Canonical: https://intel.threadlinqs.com/threat/TL-2026-2285
