Threat reportSupply ChainTL-2026-1860
Popular npm Packages in the keyv and Cacheable Namespaces Compromised in Active Supply Chain Attack
Popular npm Packages in the keyv and Cacheable Namespaces (TL-2026-1860), also tracked as Mini Shai-Hulud, is a critical-severity supply-chain compromise, first published 2026-08-04. It is attributed to TeamPCP with medium confidence, affects npm keyv, maps to 14 MITRE ATT&CK techniques (T1005, T1027, T1036), and is covered by 9 detection rules and 32 indicators of compromise.
- Severity
- CRITICALAssessed severity
- CVEs
- 0None referenced
- Techniques
- 14MITRE ATT&CK
- Actors
- 1TeamPCP
- Detection rules
- 9SPL · KQL · Sigma
- IOCs
- 32Indicators of compromise
Key facts for TL-2026-1860
- Threat ID
- TL-2026-1860
- Also known as
- Mini Shai-Hulud, Miasma, TeamPCP Campaign
- Severity
- CRITICAL
- Status
- ACTIVE
- Category
- SUPPLY_CHAIN
- First published
- Last reviewed
- Attribution
- TeamPCP
- Attribution confidence
- MEDIUM
- Motivation
- FINANCIAL
- Target sectors
- software-development, technology, cloud-services, financial-services, government administration, health
- Target regions
- Global
- Detection rules
- 9
- Indicators of compromise
- 32
Malware and tooling in Popular npm Packages in the keyv and Cacheable Namespaces
Malware and tooling: Math_Symbol.js, Miasma, Shai-Hulud, Bun v1.3.13
How Popular npm Packages in the keyv and Cacheable Namespaces works
Maintainer account jaredwray was compromised to publish malicious versions of keyv (6.0.0) and 10+ packages across the keyv and cacheable ecosystems on August 4, 2026. A malicious preinstall hook (setup.mjs) downloads a standalone Bun 1.3.13 runtime to execute a second-stage credential-stealing payload (Math_Symbol.js, ~728 KB) with self-propagation via npm OIDC trusted publishing, DNS exfiltration, and AI coding agent persistence through .claude/settings.json and .vscode/tasks.json.
On August 4, 2026, the npm maintainer account 'jaredwray' was compromised and used to publish malicious versions of keyv (6.0.0) and at least ten additional packages across the keyv and cacheable namespaces. These packages are extremely widely used (keyv alone ~154M weekly downloads and 1,700+ dependents) and serve as transitive dependencies of common tooling such as ESLint, meaning most victims never install them directly. The attack is a continuation of the TeamPCP 'Miasma' / 'Mini Shai-Hulud' self-propagating worm campaign first documented in March 2026, which was the first documented supply chain attack to weaponize AI coding agent configuration files as persistence vectors. The malicious keyv@6.0.0 hijacked the legitimate v6.0.0 release that the maintainer had announced for mid-to-late July 2026; the attacker force-pushed to main, deleted and recreated the v6.0.0 tag, and manipulated CI/CD pipelines in real time.
Delivery was carefully crafted: the published library code in dist/ was byte-identical to the last clean release, and all malicious behavior lived in an added preinstall hook in package.json ('preinstall': 'node setup.mjs', with files: [dist, LICENSE, setup.mjs, Math_Symbol.js]). The package behaves normally after install, but the host is already compromised by that point. Stage 1 (setup.mjs) is a lightly obfuscated Node script that detects platform and architecture (including Alpine/musl via ldd --version and /etc/os-release), downloads a standalone Bun 1.3.13 runtime from the official github.com/oven-sh/bun GitHub releases, unzips it (system unzip, or PowerShell Expand-Archive on Windows, or a pure-JS ZIP fallback parser), and executes the second stage under the freshly fetched Bun binary. Running under Bun sidesteps host Node version restrictions and Node-level monitoring.
Stage 2 (Math_Symbol.js, ~728 KB Bun bundle) protects its strings with polymorphic basE91 encoding - one shared numeric opcode table drives dozens of per-scope alphabets decoded lazily, requiring reimplementation of basE91 and brute-forcing each alphabet to recover strings. It targets cloud provider credentials (AWS instance metadata at 169.254.169.254 and 169.254.170.2, credential chains, Secrets Manager across all regions; GCP service account private keys; Azure client secrets), secrets management (HashiCorp Vault tokens from /home/runner/.vault-token and /run/secrets/VAULT_TOKEN), container orchestration (Kubernetes service account tokens from /var/run/secrets/kubernetes.io/serviceaccount/token), CI/CD (GitHub Actions OIDC request tokens, org and repo secrets), and package registry credentials (npm tokens via registry whoami and token endpoints). It also performs a TruffleHog-style regex sweep for keys, bearer tokens, and private key blocks on disk. Internal module log tags include [collector], [dispatcher], [provenance], and [publish].
The payload turns credential theft into a worm by calling registry.npmjs.org/-/whoami to identify the victim, searching the registry for other packages the compromised token can reach, minting publish credentials via the npm OIDC token exchange endpoint (registry.npmjs.org/-/npm/v1/oidc/token/exchange/package/), and for each discovered package downloading the tarball, injecting the same preinstall hook plus payload files, recomputing integrity and shasum, bumping the version, and PUT-ing to the registry. Where npm OIDC trusted publishing is available, republished versions inherit valid provenance - as the blog notes, 'provenance attests build integrity, not source integrity.' The initial keyv@6.0.0 shipped with a passing attestation.
Exfiltration uses no fixed C2 host. Two channels are used: a GitHubSender that creates repositories via POST /user/repos and commits stolen findings using GraphQL's createCommitOnBranch mutation, and a DomainSender that exfiltrates stolen data over DNS. The source repository also plants autostart hooks that activate without npm install: .claude/settings.json (a SessionStart hook that executes the loader when an AI coding agent opens the cloned repo) and .vscode/tasks.json (a folderOpen task that executes the loader when a developer opens the repo in VS Code).
Any environment that installed an affected version and ran install scripts should be treated as fully compromised. The impact extends to developer workstations and CI runners, where the payload can exfiltrate cloud provider keys, Vault/Kubernetes tokens, GitHub/npm credentials, and any secrets matching its regex sweep. A single compromised CI token can extend the campaign to additional packages via self-propagation. The presence of @thiennq/docs-viewer (a package published by a separate account) in the compromised set suggests the OIDC-driven propagation may have spread beyond the jaredwray namespace. No CVE has been assigned yet; detection is behavioral and artifact-based.
MITRE ATT&CK techniques used in TL-2026-1860
Collection
Defense Evasion
T1027 Obfuscated Files or Information; T1036 Masquerading; T1574 Hijack Execution Flow
Execution
T1059 Command and Scripting Interpreter; T1204 User Execution
Command and Control
T1071 Application Layer Protocol
Initial Access
T1078 Valid Accounts; T1195 Supply Chain Compromise
Discovery
T1082 System Information Discovery
Persistence
T1098 Account Manipulation; T1546 Event Triggered Execution
Credential Access
T1528 Steal Application Access Token; T1552 Unsecured Credentials
Affected products and versions in Popular npm Packages in the keyv and Cacheable Namespaces
- npm — keyv
Vulnerable versions: 6.0.0
Fixed in: <6.0.0 - npm — cacheable
Vulnerable versions: 2.5.1
Fixed in: <2.5.1 - npm — cacheable-request
Vulnerable versions: 13.0.20
Fixed in: <13.0.20 - npm — flat-cache
Vulnerable versions: 6.1.24
Fixed in: <6.1.24 - npm — cache-manager
Vulnerable versions: 7.2.10
Fixed in: <7.2.10 - npm — @cacheable/net
Vulnerable versions: 2.1.1
Fixed in: <2.1.1 - npm — @cacheable/node-cache
Vulnerable versions: 3.1.2
Fixed in: <3.1.2 - npm — @cacheable/memory
Vulnerable versions: 2.2.1
Fixed in: <2.2.1 - npm — @cacheable/utils
Vulnerable versions: 2.5.1
Fixed in: <2.5.1 - npm — @file-entry-cache
Vulnerable versions: 11.1.6
Fixed in: <11.1.6
Remediation for Popular npm Packages in the keyv and Cacheable Namespaces
Patches
- Pin keyv to <6.0.0
- Pin cacheable to <2.5.1
- Pin cacheable-request to <13.0.20
- Pin flat-cache to <6.1.24
- Pin cache-manager to <7.2.10
- Pin @cacheable/net to <2.1.1, @cacheable/node-cache to <3.1.2, @cacheable/memory to <2.2.1, @cacheable/utils to <2.5.1
Immediate actions
- Pin to the last clean version below the malicious release and rebuild lockfiles
- Rotate every credential reachable from any affected host: npm tokens, GitHub PATs and GITHUB_TOKEN, AWS/GCP/Azure keys, Vault tokens, Kubernetes service account tokens, CI org/repo secrets
- Revoke (not just rotate) npm and GitHub tokens
- Block the keyv, @keyv, and cacheable scopes in registry proxies/allowlists where practical
Workarounds
- Disable npm install scripts globally with --ignore-scripts
- Use exact versions locked by integrity hash, avoiding caret/tilde ranges and npm update
- Hunt endpoints for node setup.mjs spawning a downloaded bun, bun-dl-* temp dirs, Math_Symbol.js/math_init.js on disk, and cloud metadata reads from build agents
Longer-term hardening
- Enable npm OIDC provenance requirements for all internal packages and treat provenance as build-integrity only, not source-integrity
- Audit npm accounts for unexpected versions published on August 4, 2026
- Audit GitHub for newly created repositories and unexpected commits
- Deploy behavioral detection for install-time script activity and runtime fetching of standalone runtimes
Weaknesses (CWE) in Popular npm Packages in the keyv and Cacheable Namespaces
Timeline of Popular npm Packages in the keyv and Cacheable Namespaces
- TeamPCP 'Miasma' / 'Mini Shai-Hulud' self-propagating npm worm campaign begins; first documented supply chain attack to use AI coding agent config files for persistence.
- Miasma worm compromises TanStack (42 packages), Mistral AI, UiPath, Guardrails AI, and LiteLLM using the same Bun runtime + OIDC propagation + .claude/settings.json / .vscode/tasks.json persistence.
- Miasma worm hits 73 Microsoft GitHub repositories in 105 seconds after a malicious commit lands in Azure/durabletask; propagation uses Bun runtime, GitHub GraphQL exfiltration, and IDE/AI-agent config persistence.
- keyv maintainer announces v6.0.0 stable release planned for mid-to-late July 2026, making the namespace a high-value target for account takeover.
- Socket.dev publishes detailed analysis of the active supply chain compromise; malicious versions still live on npm at time of writing. No CVE assigned yet.
- Source repository plants autostart hooks in .claude/settings.json (Claude Code SessionStart hook) and .vscode/tasks.json (VS Code folderOpen task) that execute the loader without npm install.
- Threat actor force-pushes to jaredwray/keyv, deletes and recreates the v6.0.0 tag, and commits titled 'add setup.mjs and Math_Symbol.js to all @keyv/* packages' appear; CI/CD pipelines manipulated in real time.
- 15:39-15:44 UTC burst of malicious packages published across the cacheable family (cacheable@2.5.1, cacheable-request@13.0.20, flat-cache@6.1.24, cache-manager@7.2.10, @cacheable/* v2-v3, @file-entry-cache@11.1.6, @thiennq/docs-viewer@1.6.2).
- jaredwray npm account compromised; malicious keyv@6.0.0 published at 14:05 UTC with a malicious preinstall hook (setup.mjs) and second-stage payload (Math_Symbol.js).
Sources cited for Popular npm Packages in the keyv and Cacheable Namespaces
- Socket.dev: Popular npm Packages in the keyv and Cacheable Namespaces Compromised in Active Supply Chain Attack
- Socket.dev Analysis: keyv 6.0.0 package.json
- Socket.dev Analysis: keyv 6.0.0 setup.mjs
- Security Joes: Shai-Hulud Miasma - When a Supply Chain Worm Learned to Hijack AI Coding Agents
- Cloud Security Alliance: Research Note - Mini Shai-Hulud Supply Chain / AI Pipeline
- Dataminr: TeamPCP / Shai-Hulud 3.0 Intel Deep Dive
- Morphisec: It's In Your AI Assistant Now - Shai-Hulud Wave 3 and the Miasma Worm Targeting npm
- Socura: Supply Chain Worm Campaign Updates - Miasma / TeamPCP VS Code Exploit
- CISA: Widespread Supply Chain Compromise Impacting npm Ecosystem
- npm Registry: keyv package page
- npm Registry: cacheable-request package page
- GitHub: jaredwray/cacheable monorepo
- GitHub: jaredwray/keyv issue #1834 (v6.0.0 release plan)
Detection coverage for TL-2026-1860
As of 2026-08-04, Threadlinqs Intelligence publishes 9 detection rule(s) for TL-2026-1860 across Splunk SPL, Microsoft KQL and Sigma, covering 32 indicator(s) of compromise. The whole corpus is readable without an account; a free account unlocks full detection query text in Splunk SPL, Microsoft KQL and Sigma; paid tiers add raw indicator values, correlation and the MCP server. Threadlinqs MCP server · View plans.