Threat reportSupply ChainTL-2026-1860

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

criticalACTIVE

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

T1005 Data from Local System

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

CWE-494, CWE-506, CWE-912, CWE-829

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

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.

9 detection rules (Splunk SPL, Microsoft KQL, Sigma) · Blue and above. Compare plans
32 indicators of compromise · Red and above. Compare plans

Further reading

Threadlinqs Intelligence — Real-Time Threat Detection Platform

[ 0 threats ] [ 0 det ] [ CRIT: 0 ] [ HIGH: 0 ]
// threat_feed
$ sort --newest
Showing all threats

Live intelligence console

Threat level
Fig. 01 · Threat weatherIndexing the archive…
1 square = 1 threat · click to open

Latest Threats