Skip to content
All briefings

npm supply chain attacks, autumn 2026: ChainDrop to GhostAction

ChainDrop, SubQuery, Tensorlake and GhostAction hit npm and GitHub from August to October 2026. Affected versions, IOCs, cleanup order and hardening.

npm supply chain attacks cover with the npm logo: an isometric attack path from a hijacked maintainer account to a malicious release, credential theft, and pinning and rotation.
In short

Between August and October 2026, attackers used hijacked maintainer accounts and tokens to ship credential-stealing code through trusted release pipelines: the ChainDrop worm in keyv and hundreds of other packages, @subql/common 5.8.3, tensorlake 0.5.144, and GhostAction workflows in GitHub repositories. All are active attacks. Pin clean versions, remove any gh-token-monitor service before revoking GitHub tokens, then rotate credentials from a clean machine.

The attack path

Four steps, from the way in to the fix.

Between August and October 2026, attackers repeatedly took over a maintainer's account or token and shipped malicious code through the project's own release pipeline, so the packages carried valid npm provenance. Then they used the stolen credentials to reach the next package or repository. The newest variant adds a trap: revoke the stolen GitHub token too early and it wipes your home directory.

It started on 4 August 2026, when keyv and its sibling caching packages shipped a self-spreading worm that Microsoft calls ChainDrop and others call Mini Shai-Hulud. On 5 October, a tampered SubQuery workflow published @subql/common 5.8.3. On 8 October, tensorlake 0.5.144 shipped the same worm family with a destructive token monitor. From 8 to 12 October, the GhostAction campaign pushed fake "Security Audit" workflows into more than 30,000 GitHub repositories, by GitGuardian's count.

Which packages were affected

IncidentPublished (UTC)MaliciousClean
ChainDrop4 August, from 09:35keyv 6.0.0, flat-cache 6.1.24, file-entry-cache 11.1.6, cacheable 2.5.1, cache-manager 7.2.10, cacheable-request 13.0.20, @cacheable packages, ecto 5.0.1, then hundreds moreVersions published before 09:30 UTC on 4 August
SubQuery5 October, 11:56@subql/common 5.8.35.8.2
Tensorlake8 October, 01:12tensorlake and tensorlake-native-* 0.5.1440.5.143, or 0.5.145
GhostAction8–12 October (earlier wave 31 August–30 September)None; injected GitHub workflowsNot applicable

keyv and its siblings usually arrive as transitive dependencies. SubQuery packages such as @subql/cli and @subql/node-core accept 5.8.3 through their version ranges.

The counts are disputed. For ChainDrop, Microsoft says more than 400 packages, Aikido at least 444 packages and 1,381 versions, and GitGuardian more than 800 packages. Endor Labs verified 1,136 versions across 384 packages and calls that a floor. For GhostAction, Socket first counted 346 repositories. GitGuardian reports more than 30,000 repositories and about 1,900 compromised accounts on 8–9 October.

How the attacks worked

Earlier, on 29 April 2026, four SAP packages (mbt and three @cap-js database packages, CVE-2026-46421) shipped a Bun-loaded stealer through a static npm token and a repository-wide trusted publisher.

ChainDrop

The attacker compromised the keyv maintainer's GitHub account and pushed to main, and the release pipeline published it. A preinstall hook runs setup.mjs, which downloads Bun and runs an obfuscated payload, Math_Symbol.js or later math_init.js. It steals npm, GitHub, cloud, Kubernetes and Vault credentials, SSH keys and CI runner memory. It republishes every package a stolen npm token can write, and commits .claude/settings.json and .vscode/tasks.json hooks that rerun it when the repository is opened. Data goes to public repositories described "Shai-Hulud: Here We Go Again" or to an attacker endpoint.

SubQuery

Unsigned commits on a short-lived branch changed the publish workflow to swap the built package for a tarball from ci-artifacts.dev, unverified, before publishing through OIDC. How the attacker got push access is not public; the maintainer said only that a compromised token was deleted. The payload runs on install and on import. It steals local and cloud secrets, pushes a secret-dumping workflow and opens a reverse shell on command. Sources disagree on that workflow: StepSecurity reports codeql_analysis.yml, Flatt Security one presented as "Run Copilot". No source ties SubQuery to Mini Shai-Hulud, though it injects the same branch name as the Tensorlake worm.

Tensorlake

Tensorlake says a compromised maintainer account pushed straight to main, and its release workflow published 0.5.144. The loader lib/setup.mjs fetches Bun and runs lib/Math_Symbol.js, which also takes AI tool and MCP configs, browser passwords and wallets. The new piece is gh-token-monitor, a user service that checks the stolen GitHub token every 60 seconds for up to 24 hours and deletes the home directory if GitHub rejects it.

GhostAction

With stolen maintainer credentials, the operator committed .github/workflows/security-audit.yml (earlier: github_actions_security.yml, security-check.yml), triggered on every push. It sends the repository's Actions secrets and searches files and full git history for cloud, source-control and AI keys, posting them in cleartext to 193.32.204.199. Reports that personal access tokens were the entry point are unconfirmed; Socket says it did not observe how access was obtained.

Is it being exploited?

Yes. Tensorlake and SubQuery acknowledged compromised credentials, and Microsoft, StepSecurity, Aikido, Endor Labs, Socket and GitGuardian documented the payloads.

How much was stolen is less clear. Tensorlake saw no use of 0.5.144 during its roughly 100 minutes on npm, though StepSecurity found it still downloadable when it checked. StepSecurity found no repository where SubQuery's workflow ran. GitGuardian reports GitHub began blocking the GhostAction workflow on 9 October; later runs extracted no secrets.

Were you affected?

Read-only checks
# Known-bad versions in the resolved tree
npm ls keyv flat-cache file-entry-cache cache-manager @subql/common tensorlake --all \
  | grep -E 'keyv@6\.0\.0|flat-cache@6\.1\.24|file-entry-cache@11\.1\.6|cache-manager@7\.2\.10|@subql/common@5\.8\.3|tensorlake@0\.5\.144'
 
# Tensorlake token monitor (do not revoke tokens yet if present)
ls -la ~/.config/gh-token-monitor ~/.local/bin/gh-token-monitor.sh 2>/dev/null
 
# SubQuery worker and lock file
ps -eo pid,args | grep '[m]anifest-cache.js'
ls /tmp/tmp.ts018051808.lock 2>/dev/null
 
# Repository persistence and GhostAction workflows
git log --all --oneline -- .claude/settings.json .vscode/tasks.json \
  .github/workflows/security-audit.yml .github/workflows/github_actions_security.yml

Unpublished versions no longer resolve, so also search old lockfiles and CI logs.

Published SHA-256 hashes
54dc7ea54a1317cca0e890a2770630cf7fa6c97813e0cb9d2caa93012b350668  setup.mjs (ChainDrop)
fd3ca4007b225fdf8de7af4345a19179d5efa8c4bb9205f88cda806e5684b1eb  setup.mjs (ChainDrop, later)
9fc2570b7cef51c1b8df116d144d11ff4096357be7d2c4c6367cfc2509cf1bcc  Math_Symbol.js / math_init.js
031267ee37c5a84c25cb0542cbfeb49f30d5604305b0bdccdeafbedcbbe6849b  @subql/common 5.8.3 tarball
25a0735d0db7dc40e5d45ce42d9c106067e6a66e184d967cfecfab17c3bcb5ef  lib/setup.mjs (Tensorlake)
b50a00900399ba99fb6ce1fc151519cb99d44320ef2a631f2237e1aea0ad6fec  lib/Math_Symbol.js (Tensorlake)

Clean up

  1. Disconnect, then remove the monitor. Remove gh-token-monitor before revoking any GitHub token, following Tensorlake's advisory.
  2. Pin clean versions. Override transitive keyv packages, delete node_modules and purge npm and yarn caches, including CI caches.
  3. Rotate from a clean machine. npm, GitHub, cloud, Kubernetes, Vault, SSH, CI and AI tool credentials.
  4. Rebuild. Uninstalling does not stop SubQuery's detached worker.
  5. For GhostAction, revoke the GitHub credential that pushed the workflow; GitGuardian warns rotating stolen secrets alone is not enough. Then rotate exposed secrets and remove the workflow.

Detect attempts and compromise

  • Install time. node setup.mjs in a preinstall step, Bun downloaded during npm install, bun-dl- temporary directories.
  • Network. npm-cache[.]com, pypi-get[.]com, js-mirror[.]com, ci-artifacts[.]dev (185.146.234.137 per Flatt), iseekaigogo[.]com, 193.32.204.199.
  • GitHub. Public repositories described "Shai-Hulud: Here We Go Again", the branch dependabot/github_actions/format/setup-formatter, commits from [email protected].

If any fired, treat every credential on that host or runner as stolen.

Harden your publishing and installs

npm 12, generally available since 8 July 2026, skips dependency install scripts unless your project approves them. That stops preinstall loaders like ChainDrop's and Tensorlake's. It does nothing for SubQuery's import-time trigger, older npm releases still run scripts, and GhostAction never touched npm.

  • Scope trusted publishing to one workflow and branch, and retire static tokens (StepSecurity; GitHub).
  • Gate release workflows with approvals and protected environments (Microsoft).
  • Keep a committed script allowlist (GitHub) or ignore-scripts=true (StepSecurity).
  • Set min-release-age; Flatt suggests seven days (Microsoft, Flatt).
  • Review .claude/ and .vscode/tasks.json changes as code (StepSecurity).
  • Enable secret scanning with push protection, require approval for outside collaborators' workflow runs, and enforce phishing-resistant MFA (Socket).
  • Allow-list CI runner egress (StepSecurity).

Beyond this patch

Each incident passed the checks teams usually trust: provenance, a trusted publisher, a familiar maintainer. Treat release pipelines and developer machines as production systems, and plan revocations before a token becomes a hostage.

Frequently asked questions

Am I affected if I never installed keyv or tensorlake directly?

Possibly. keyv, flat-cache and file-entry-cache usually arrive as transitive dependencies, and several SubQuery packages accept @subql/common 5.8.3 through their version ranges. Check the resolved tree with npm ls --all, and search old lockfiles and CI logs, because the main malicious versions have been removed from npm and no longer appear in fresh installs. Treat any machine or runner that installed one as compromised.

Why remove gh-token-monitor before revoking GitHub tokens?

The Tensorlake payload installs a user service called gh-token-monitor that checks the stolen GitHub token every 60 seconds for up to 24 hours. If GitHub rejects the token, for example because you revoked it, the service deletes your home directory. Disconnect the machine, remove the service using the steps in Tensorlake's advisory, then rotate credentials from a different, clean machine and rebuild.

Does npm 12 protect me from these attacks?

Partly. npm 12, generally available since 8 July 2026, skips dependency preinstall, install and postinstall scripts unless your project approves them, which stops loaders like ChainDrop's and Tensorlake's. It does not stop SubQuery's payload, which also runs when the package is imported. It does not help machines still on older npm releases, and GhostAction never used npm at all.

How do I check whether GhostAction hit my repositories?

Search every repository the account could write to for .github/workflows/security-audit.yml, github_actions_security.yml or security-check.yml, review Actions run history for those workflows, and look for outbound connections to 193.32.204.199. Socket advises treating any completed run as successful theft of the named secrets. Revoke the GitHub credential that pushed the workflow, not only the secrets it read.

Is npm provenance enough to trust a package?

No. ChainDrop's first wave and the SubQuery and Tensorlake releases were all published through the projects' own trusted-publishing pipelines and carried valid provenance. An attestation tells you which workflow built a package, not whether its code is safe. Pair it with a release cooldown such as npm's min-release-age, trusted publishing scoped to one workflow and branch, and approvals on release workflows.

Sources

  1. Tensorlake security advisory GHSA-8g63-53c9-65j2 (tensorlake 0.5.144)
  2. tensorlakeai/tensorlake issue #1014 — malicious preinstall payload in 0.5.144
  3. subquery/subql issue #3047 — malicious release @subql/[email protected]
  4. GitHub Changelog — npm install-time security and GAT bypass-2FA deprecation (8 Jul 2026)
  5. GitHub Changelog — Upcoming breaking changes for npm v12 (9 Jun 2026)
  6. GitHub Advisory GHSA-pvw4-cvr4-97p8 (CVE-2026-46421, SAP @cap-js packages)
  7. Microsoft Security — ChainDrop supply chain compromise: anatomy of a self-propagating worm
  8. StepSecurity — SubQuery ecosystem compromise
  9. StepSecurity — Tensorlake npm package compromised: a worm with a hostage token
  10. StepSecurity — A Mini Shai-Hulud has appeared (SAP packages)
  11. Aikido — Keyv and friends compromised in npm supply chain attack
  12. Endor Labs — npm malware compromises keyv and cacheable
  13. GitGuardian — Mini Shai-Hulud's latest wave (keyv)
  14. GitGuardian — GhostAction returns
  15. Socket — New GhostAction wave expands to cloud credentials
  16. GMO Flatt Security — @subql/common supply chain attack

Published 28 October 2026 · By the Rokkhe research team