ChainDrop Shai-Hulud npm Attack: Keyv, Cacheable and Hundreds of Packages Compromised
A new wave of the Shai-Hulud software-supply-chain campaign compromised the maintainer behind widely used npm packages including Keyv and Cacheable, then spread into hundreds of additional packages by stealing credentials and abusing legitimate publishing access.
Security firm Aikido says the campaign began on August 4, 2026, when attackers compromised the GitHub account of the maintainer behind keyv. The attackers pushed malicious files directly to project branches and cut new npm releases through legitimate GitHub Actions workflows, so poisoned packages could still carry valid provenance.
The campaign’s package count changed quickly as researchers tracked new propagation. Contemporary reports citing Aikido’s evolving August 5 tally ranged from 444 to 868 unique packages, while 1,381 referred to compromised package versions. Those packages collectively represented more than 2 billion monthly downloads in the researchers’ estimates. Because the campaign was still moving, teams should use a current affected-version feed rather than treating any single headline count as exhaustive.
The practical response is more important than the headline number: if an affected package version executed on a developer workstation or CI/CD runner, removing or downgrading the package is not enough. Treat the environment and its reachable credentials as potentially compromised.
Confirmed affected packages include major caching utilities
Aikido’s initial investigation identified malicious releases across a family of heavily used JavaScript caching packages:
| Package | Malicious version reported by Aikido | Approx. monthly installs reported by Aikido |
|---|---|---|
keyv | 6.0.0 | 604M |
flat-cache | 6.1.24 | 580M |
file-entry-cache | 11.1.6 | 571M |
cacheable-request | 13.0.20 | 137M |
cacheable | 2.5.1 | 30M |
@cacheable/memory | 2.2.1 | 28M |
cache-manager | 7.2.10 | 16M |
@cacheable/node-cache | 3.1.2 | 6M |
Aikido also observed spread into packages associated with other maintainers and organizations, including Deliveroo, Ornikar, Picsart and Qlik.
Because the worm steals credentials and republishes packages it gains rights to, the affected-package list is not static. Teams should rely on current security advisories, registry metadata and live malware feeds rather than assuming that only the first disclosed packages are relevant.
How ChainDrop executes
The malicious package versions added a preinstall hook:
"preinstall": "node setup.mjs" That matters because a preinstall hook runs as part of dependency installation, before an application ever imports the affected package.
Aikido says setup.mjs acts as an obfuscated dropper. It downloads the Bun JavaScript runtime and uses Bun to execute a much larger payload called Math_Symbol.js.
The payload is not limited to one credential type. It is designed to inspect developer machines, CI environments and cloud-access material, then encrypt and exfiltrate what it finds.
What the malware tries to steal
Aikido’s analysis shows the payload targeting several high-value credential classes.
npm publishing tokens
The malware reads ~/.npmrc and searches for additional .npmrc files, extracting npm authentication tokens. It can validate tokens against npm before using them.
This is central to the worm’s propagation model: a stolen npm token may grant publishing rights to other packages maintained by the same developer or organization.
GitHub credentials and CI identities
The payload looks for GitHub personal access tokens, OAuth tokens, GitHub App server-to-server tokens and OIDC-related material.
On GitHub Actions runners, Aikido says the malware attempts to read runner-process memory to recover secrets and OIDC tokens used by publishing workflows.
That means a compromise can extend beyond source code and into the identities used to publish otherwise trusted artifacts.
AWS credentials and cloud metadata
The malware targets standard AWS credential files and environment variables, EC2 instance metadata, ECS container metadata and AWS Secrets Manager.
If a compromised CI runner has broad cloud permissions, the blast radius can therefore be much larger than npm itself.
Kubernetes secrets
Aikido says the payload reads Kubernetes service-account credentials and attempts to use them against the Kubernetes API. It also searches common kubeconfig locations.
Vault, SSH, Terraform and other developer secrets
The filesystem scanner targets files including .env files, private keys, SSH credentials, Terraform state and variable files, Docker credentials, KeePass databases, VPN configurations and IDE configuration files.
Aikido also observed checks for Stripe keys and Slack tokens.
The worm can spread through npm and GitHub
ChainDrop is dangerous because credential theft is only one part of its behavior.
npm propagation
When the malware obtains a usable npm token, Aikido says it enumerates packages the token can publish, downloads their current tarballs, injects the malicious preinstall files, increments versions and republishes them.
That turns a single maintainer compromise into a supply-chain multiplier: every newly poisoned package can infect additional developer or CI environments, generating more credentials that can be used to continue propagation.
GitHub repository propagation
The malware also abuses GitHub credentials. Aikido observed it modifying reachable repositories and adding malicious execution hooks to files such as:
.claude/settings.json.vscode/tasks.json
Those hooks can trigger when a developer opens a repository in VS Code or starts Claude Code inside it, meaning execution is no longer limited to an npm install event.
Aikido says these commits may appear under the author name claude with the commit message chore: update config, an attempt to make malicious changes blend into ordinary developer activity.
Valid provenance did not mean the package was safe
One of the more important lessons from this incident is that artifact provenance is not the same thing as artifact safety.
Aikido says the attackers committed malicious files directly into legitimate repositories and then released the packages using existing GitHub Actions workflows. The resulting npm releases could therefore be signed by the legitimate build pipeline and carry valid provenance.
Provenance can answer questions such as where an artifact was built and which workflow produced it. It cannot prove that the source code entering that trusted workflow was benign.
This is exactly the failure mode supply-chain teams need to design for: a trusted pipeline can faithfully build and sign malicious source if the repository or maintainer identity has already been compromised.
Why npm v12’s security defaults help — but do not solve this incident class
GitHub has already been hardening npm in response to earlier supply-chain campaigns.
With npm v12, dependency lifecycle scripts such as preinstall, install and postinstall are disabled by default unless explicitly approved. That is directly relevant to malware that relies on automatic preinstall execution.
GitHub has also introduced publish-time malware scanning, and npm trusted publishing can use OIDC instead of long-lived publish tokens. Staged publishing is separately available for workflows that require human approval before a package becomes installable.
These changes raise the attacker’s cost, but they do not remove the need to secure maintainer accounts, GitHub repositories and CI identities. ChainDrop demonstrates why: an attacker who compromises trusted source repositories or developer identities can still abuse legitimate build and publication paths.
What developers and security teams should do now
If you installed or built with an affected version, treat incident response as a host-and-credential compromise problem rather than merely a dependency rollback.
1. Identify exposure
Check lockfiles, CI logs, dependency caches and artifact histories for affected package versions. Do not rely only on the currently installed package tree; a poisoned package may have executed earlier and then disappeared after a later update.
Pay particular attention to developer workstations and CI runners that performed installs while the malicious versions were available.
2. Isolate affected environments
If a poisoned package executed, isolate the workstation or CI runner from sensitive environments until you understand what credentials were reachable.
Ephemeral CI runners should be destroyed and recreated from a trusted image rather than reused.
3. Check for Shai-Hulud persistence before revoking credentials
This ordering matters. Recent Shai-Hulud variants have installed a gh-token-monitor persistence mechanism on Linux and macOS that watches a stolen GitHub token and can trigger a destructive handler when the token is revoked.
Before rotating GitHub or npm credentials from an affected environment, check for indicators including:
~/.local/bin/gh-token-monitor.sh~/.config/gh-token-monitor/~/.config/systemd/user/gh-token-monitor.service~/Library/LaunchAgents/com.user.gh-token-monitor.plist
If these or equivalent persistence artifacts are present, disable and remove the persistence and terminate the running process first. Perform credential rotation from a separate, known-clean system. Do not execute untrusted cleanup scripts from the compromised host.
4. Rotate npm and GitHub credentials from a clean system
After persistence has been addressed, rotate npm tokens, GitHub PATs, OAuth credentials and any affected GitHub App credentials. Review repository access and publishing rights for unexpected changes.
For automated npm publishing, move away from broad long-lived tokens where possible and use tightly scoped trusted publishing/OIDC workflows.
5. Rotate reachable cloud and infrastructure secrets
If the environment held AWS credentials, Kubernetes service-account tokens, Vault tokens, SSH keys, Terraform secrets or other machine credentials, assume they may have been collected.
Credential rotation should be based on what the compromised host could access, not only on what you know was exfiltrated.
6. Audit repositories for malicious persistence
Search for unexpected modifications to .claude/settings.json, .vscode/tasks.json, workflow files and package scripts.
Review suspicious commits around the exposure window, especially automated-looking commits or commits that add execution hooks.
7. Rebuild from known-good state
After persistence is removed and credentials are rotated, rebuild affected developer or CI environments from trusted images. Simply deleting the malicious npm package leaves behind any credentials already stolen and may leave persistence mechanisms untouched.
Indicators published during the investigation
Aikido published the following indicators in its August analysis:
| Indicator | Value |
|---|---|
| Malicious dropper | setup.mjs |
| Main payload | Math_Symbol.js / math_init.js |
| Dropper SHA-256 | 54dc7ea54a1317cca0e890a2770630cf7fa6c97813e0cb9d2caa93012b350668 |
| Community-spread dropper SHA-256 | fd3ca4007b225fdf8de7af4345a19179d5efa8c4bb9205f88cda806e5684b1eb |
| Payload SHA-256 | 9fc2570b7cef51c1b8df116d144d11ff4096357be7d2c4c6367cfc2509cf1bcc |
| Fallback endpoint | npm-cache[.]com:443/router |
| GitHub exfiltration marker | Repository description containing Shai-Hulud: Here We Go Again |
Static indicators are useful for triage, but they should not be treated as sufficient evidence of safety. A self-propagating campaign can evolve quickly, and stolen credentials may be abused long after the original malicious file is gone.
Sources
- Aikido Security — Keyv and friends compromised in active Shai-Hulud supply chain attack
- GitHub Changelog — npm install-time security and 2FA-bypass token deprecation
- GitHub Changelog — npm publish-time malware scanning and dual-use metadata
- GitHub Changelog — npm trusted publishing with OIDC
- GitHub Changelog — staged publishing
- JFrog Security Research — Shai-Hulud gh-token-monitor persistence indicators
- Cloud Security Alliance — Mini Shai-Hulud remediation ordering
Comments
Sign in to join the discussion!
Your comments help others in the community.