Keyv and friends compromised in active Shai-Hulud supply chain attack

Hacker News Top News

Summary

Attackers compromised the GitHub account of the maintainer behind keyv and related npm caching libraries, injecting a credential-stealing worm across multiple packages with over 2 billion combined monthly installs.

No content available
Original Article
View Cached Full Text

Cached at: 08/04/26, 01:45 PM

# Keyv and friends compromised in active Shai-Hulud supply chain attack Source: [https://www.aikido.dev/blog/keyv-and-friends-compromised-in-npm-supply-chain-attack](https://www.aikido.dev/blog/keyv-and-friends-compromised-in-npm-supply-chain-attack) On August 4, 2026, attackers compromised the GitHub account of the maintainer behind`keyv`, a key\-value storage library with roughly 127 million weekly npm downloads, and used that access to inject a credential\-stealing worm across the entire package family\. The same maintainer owns`cacheable`\(29M downloads/month\),`flat\-cache`\(565M downloads/month\),`file\-entry\-cache`\(557M downloads/month\), and several other widely\-used caching utilities, all of which were swept up in the same attack\. The compromise was carried out by pushing malicious files directly to the`main`branch and then immediately cutting a new release, meaning the poisoned versions were published to npm with valid provenance signed by GitHub Actions\. **The compromised packages include:** - `keyv`6\.0\.0 \(604M/month\) - `flat\-cache`6\.1\.24 \(580M/month\) - `file\-entry\-cache`11\.1\.6 \(571M/month\) - `cacheable\-request`13\.0\.20 \(137M/month\) - `cacheable`2\.5\.1 \(30M/month\) - `@cacheable/memory`2\.2\.1 \(28M/month\) - `cache\-manager`7\.2\.10 \(16M/month\) - `@cacheable/node\-cache`3\.1\.2 \(6M/month\) - `@cacheable/utils`2\.5\.1 \(34M/month\) - `@cacheable/net`2\.1\.1 \(3\.7K/month\) - `ecto`5\.0\.1 \(4\.5K/month\) We are also also seeing very active community spread of this supply chain worm to other maintainers and packages, including major organizations: - `@deliveroo/reevent`1\.0\.1 - `@or\-sdk/invitations`1\.4\.9 - `@picsart/ai\-sdk`3\.32\.2 - `@qlik/embed\-runtime`1\.6\.4 - `picasso\.js`2\.11\.6 **Update — August 4, 2026, 13:37 CEST:**At least 868 packages \(across 1381 versions\) have been compromised by the worm, with a combined total of over**2 billion monthly installs**at the time of writing\. ## What happened Every package in the family received two new files,`setup\.mjs`and`Math\_Symbol\.js`, along with a`"preinstall": "node setup\.mjs"`entry added to each`package\.json`\. Anyone who ran`npm install`against an affected version would have had`setup\.mjs`execute automatically before their install completed\. `setup\.mjs`is a heavily obfuscated dropper\. Its only job is to silently download the Bun JavaScript runtime from github\[\.\]com/oven\-sh/bun/releases/download/bun\-v1\.3\.13/ and use it to execute the real payload,`Math\_Symbol\.js`: ``` execFileSync(<bun binary>, ['<script_dir>/Math_Symbol.js'], { stdio: 'inherit', cwd: <script_dir> }) ``` The`Math\_Symbol\.js`is a heavily obfuscated 728 KB JavaScript file containing credential stealers that harvest secrets from the victim's environment, encrypt the findings, and exfiltrate them to a public GitHub repository whose description reads "**Shai\-Hulud: Here We Go Again**"\. The payload also contains worm\-like propagation functionality to infect packages of other maintainers that have installed one of the compromised packages\. ## What it steals The`Math\_Symbol\.js`file implements a set of credential extractors, each targeting a different secret store on the victim machine\. **npm tokens** Reads`~/\.npmrc`and scans the filesystem for any other`\.npmrc`files\. Extracts`authToken`values and any`//registry\.\*:\_authToken=\.\.\.`entries\. Validates each token live against`registry\.npmjs\[\.\]org/\-/whoami`before exfiltrating\. **GitHub tokens** Three token formats are targeted: classic PATs \(`ghp\_\.\.\.`\) and OAuth tokens \(`gho\_\.\.\.`\), GitHub App server\-to\-server tokens \(`ghs\_\.\.\.`\), and JWT OIDC tokens\. Sources include`~/\.config/gh/hosts\.yml`, environment variables, and a filesystem scan\. On GitHub Actions runners, the payload also executes a shell command that reads the runner process memory directly to dump the entire secret store\. It reads`ACTIONS\_ID\_TOKEN\_REQUEST\_TOKEN`and`ACTIONS\_ID\_TOKEN\_REQUEST\_URL`to steal OIDC tokens used for npm publishing\. **AWS credentials** - `~/\.aws/credentials`and`~/\.aws/config`, parsing all named profiles - `AWS\_ACCESS\_KEY\_ID`,`AWS\_SECRET\_ACCESS\_KEY`, and`AWS\_SESSION\_TOKEN`environment variables - EC2 Instance Metadata Service at`169\.254\.169\.254`, trying IMDSv2 first with a fallback to IMDSv1 - ECS container metadata endpoint at`169\.254\.170\.2` - AWS Secrets Manager, calling`secretsmanager:ListSecrets`across multiple regions to enumerate and exfiltrate all secrets stored there **Kubernetes secrets** Reads the service account token, CA certificate, and namespace from`/var/run/secrets/kubernetes\.io/serviceaccount/`\. Uses the service account token to query the Kubernetes API directly and retrieve all secrets in the namespace\. Also targets`KUBECONFIG`and`~/\.kube/config`\. **HashiCorp Vault tokens** Checks six sources in priority order: the`VAULT\_TOKEN`environment variable,`~/\.vault\-token`, the GitHub Actions runner path`/home/runner/\.vault\-token`, several well\-known container paths, a Kubernetes auth login using the stolen service account JWT, and Vault's AWS IAM auth endpoint using any stolen AWS credentials\. After obtaining a token, it enumerates all KV stores via`/v1/sys/mounts`and reads every secret from KV v1 and v2 paths\. **Stripe and Slack tokens** Scans for Stripe API keys \(both test and live,`sk\_`and`pk\_`prefixes\) and Slack tokens \(`xox\[baprs\]\-\.\.\.`\) across all files touched by the filesystem scanner\. **Generic filesystem scan** A platform\-aware scanner \(macOS vs Linux\) runs roughly 200 glob patterns across the filesystem, targeting among other things: - `\.env`,`\.env\.\*`, and`\.envrc`files - Private key files \(`\*\.pem`,`\*\.key`,`\*\.p12`,`\*\.pfx`,`\*\.jks`\) - SSH keys and config \(`id\_rsa`,`id\_ed25519`,`\.ssh/config`\) - Terraform state files and`\.tfvars` - Docker registry credential files \(`docker/config\.json`\) - KeePass databases \(`\*\.kdbx`\) - VPN configs \(`\*\.ovpn`\) - IDE config files including`\.vscode/tasks\.json`and`\.claude/settings\.json` Files over 5 MB are skipped\. Up to 64 concurrent reads are used\. A generic regex engine is also applied across all scanned files, flagging PEM private keys, SSH public keys, Azure storage keys, database connection strings with embedded credentials, and generic`key=value`patterns matching common secret field names\. ## How Aikido detects this If you are an Aikido user, check your central feed and filter on malware issues\. This will surface as a 100/100 critical issue\. Aikido rescans nightly, but we recommend triggering a manual rescan now\. If you are not yet an Aikido user, you can[create an account](https://app.aikido.dev/login)and connect your repos\. Our malware coverage is included in the free plan, no credit card required\. For broader coverage across your whole team, Aikido's[Device Protection](https://www.aikido.dev/protect/device-protection)gives you visibility and control over the software packages installed on your team's devices\. It covers browser extensions, code libraries, IDE plugins, and build dependencies, all in one place\. Stop malware before it gets installed\. For future protection, consider[Aikido Safe Chain](https://github.com/AikidoSec/safe-chain)\(open source\)\. Safe Chain sits in your existing workflow, intercepting npm, npx, yarn, pnpm, and pnpx commands and checking packages against[Aikido Intel](https://intel.aikido.dev/)before install\.

Similar Articles

Mini Shai-Hulud Strikes Again: 314 npm Packages Compromised

Hacker News Top

The npm account 'atool' was compromised, leading to the publication of 637 malicious versions across 317 packages. The payload harvests credentials, establishes persistence via AI coding tools and system services, and exfiltrates data through GitHub.

Dozens of Red Hat packages backdoored through its official NPM channel

Ars Technica

Dozens of Red Hat packages were backdoored through the company's official NPM channel using the Shai-Hulud worm, which compromised Red Hat's CI/CD pipeline via GitHub Actions OIDC. Red Hat has removed the malicious packages and stated they were internal only, but the attack underscores escalating supply-chain risks.