MagicTools
Developer ToolsAugust 5, 20265 views5 min read

That npm install You Ran Yesterday May Have Stolen Every Key You Own

That npm install You Ran Yesterday May Have Stolen Every Key You Own

On August 4, 2026, someone pushed two malicious files to the keyv GitHub repo and cut a release tag. npm published it automatically. GitHub Actions signed the provenance. Everything looked legitimate.

One detail didn't fit: the push didn't come from the maintainer. That account had been taken over.

Anyone who ran npm install that afternoon—possibly you—quietly executed a 728KB obfuscated script. Its job was simple: collect every credential it could find, encrypt the haul, upload it to a public GitHub repository.

Description on that repo, in full: "Shai-Hulud: Here We Go Again."

Not one package. An entire chain.

keyv was just the doorway. The same maintainer also owned flat-cache (580M monthly downloads), file-entry-cache (571M/month), cacheable-request (137M/month), and eight other caching utilities. One stolen account, eleven poisoned packages.

Then came the part that makes this genuinely nasty: the worm. Math_Symbol.js doesn't stop at stealing credentials. It searches your disk for source code belonging to other npm packages, and if it decides you're a maintainer, it takes your npm token and ships an infected release under your name.

Current count: 434 packages, 1,381 versions, more than 2 billion monthly installs. @deliveroo/reevent, @picsart/ai-sdk, @qlik/embed-runtime, picasso.js—packages from serious engineering organizations, now distributing the same malware on the attacker's behalf.

What it actually steals

Read through the extractor list in Math_Symbol.js and your stomach drops:

  • npm tokens: Reads ~/.npmrc, then sweeps the whole filesystem for stray .npmrc files, pulls out every _authToken, and validates each one live against registry.npmjs.org/-/whoami
  • GitHub tokens: Classic PATs, OAuth tokens, GitHub App server-to-server tokens, JWT OIDC tokens—harvested from ~/.config/gh/hosts.yml, environment variables, and CI runner process memory
  • AWS credentials: Every named profile in ~/.aws/credentials, environment variables, EC2 Instance Metadata Service (IMDSv2, falling back to v1), ECS container metadata, plus a direct secretsmanager:ListSecrets call across regions
  • Kubernetes secrets: Grabs the service account token, asks the K8s API for every secret in the namespace, pockets kubeconfig on the way out
  • HashiCorp Vault tokens: Six sources tried in order—environment variable, ~/.vault-token, CI runner paths, K8s JWT auth, AWS IAM auth—then it walks every KV store within reach
  • Stripe & Slack tokens: Filesystem scan for anything starting with sk_ or xox
  • Generic filesystem scan: Roughly 200 glob patterns covering .env files, private keys (.pem, .key, .p12, .pfx), SSH keys, Terraform state, browser cookies, password databases. Call it "everything you'd rather nobody saw"

One line of "preinstall": "node setup.mjs" in package.json sets all of it off. Your node_modules folder isn't finished populating and your secrets are already gone.

Why signatures and 2FA didn't help

Two questions come up immediately: doesn't npm have provenance signatures? Isn't 2FA mandatory now?

Here's the uncomfortable part. Once an attacker controls the maintainer's GitHub account, the packages they publish are indistinguishable from the real thing.

GitHub Actions OIDC tokens belong to the runner, not to a person. Push malicious code to main, tag a release, and the pipeline builds, signs, and publishes on its own. Every step passes inspection, because as far as GitHub can tell, the "maintainer" is doing it.

2FA fares no better. A stolen session cookie or OAuth token gets an attacker through the door without ever triggering a second factor—no password, no code, just a cookie that hasn't expired yet. That's session hijacking.

Dependency risk isn't only about malware

August 4 produced two dependency stories, not one. Bending Spoons also announced it was acquiring Airtable for $1.3 billion.

Different mechanism, same lesson: the things you depend on are not under your control.

Keyv is "someone deliberately broke it." Airtable is "the company changed hands and pricing is about to move." Either way, a developer building on that foundation ends up in the same place—your stack is suddenly someone else's decision.

Bending Spoons runs a consistent playbook: acquire, cut headcount, raise prices, shrink the free tier. Expect reduced free API quotas, repackaged plans, and a few features quietly retired. Teams running automation on Airtable—plenty use it as a no-code backend—should start sketching a migration path now. Not because Airtable disappears tomorrow, but because the free ride most likely ends when the deal closes at the end of 2026.

Call that risk management, not FUD.

Five things you can do today

Don't panic, but don't close the tab either. In priority order:

1. Check your lockfile (5 minutes)

grep -E "keyv|flat-cache|file-entry-cache|cacheable|cache-manager" package-lock.json yarn.lock 2>/dev/null

Got a hit? Check the version. Known-affected releases include keyv 6.0.0, flat-cache 6.1.24, and file-entry-cache 11.1.6. Upgrade to a clean version, then rotate every token that machine has ever touched.

2. Turn off install scripts (10 minutes)

npm config set ignore-scripts true

No more automatic preinstall and postinstall hooks. You'll pay for it with the occasional manual npm rebuild for native modules, which I'd argue is a bargain. Want something softer? Run one full install with --ignore-scripts and inspect the tree before you commit to anything.

3. Add a dependency review step to CI (30 minutes)

For GitHub Actions:

- name: Audit dependencies
  run: |
    npm audit --audit-level=high
    npx socket scan

Not ready for new tooling? Then confirm two things: your lockfile is committed, and CI runs npm ci rather than npm install.

4. Rotate credentials—right now, if you installed yesterday

Ran npm install on August 4 with an affected package in your lockfile? Start rotating:

  • npm tokens: regenerate at npmjs.com, revoke every old one
  • GitHub PATs: Settings → Developer settings → Personal access tokens
  • AWS access keys: IAM → Users → Security credentials
  • Every API key sitting in ~/.env on that machine

The script went looking for exactly these. Rotating them isn't paranoia.

5. Map your single points of failure (this week)

Open a blank note and answer three questions:

  • Which third-party services would take my product down if they vanished? (Skip database, CDN, and auth—you already worry about those. Hunt for the ones you never think about.)
  • Which npm packages would take me longest to replace if they were compromised or pulled?
  • Which SaaS products would break my cost model if they doubled their price?

Write the answers down. No action plan required yet. The gap between "I know" and "I never thought about it" is the gap between a bad afternoon and a bad quarter.


Supply chain attacks aren't going away. AI writes more of our code every month, dependency trees keep getting deeper, and the attack surface grows right along with them.

So don't just nod and move on. Open a terminal and run that grep from step one—two minutes, start to finish. If something comes back, you'll be glad you didn't wait until tomorrow.

✨ Draft generated by DeepSeek, reviewed and polished by Claude.

Sources:

Related Articles

I Put My Opus 5 Config on the Recommended Diet, Then Ran 18 A/B Trials: 21% Cheaper, and I Can't Prove It's Better

"Opus 5 verifies itself, so delete your fallback prompts" is advice you hear everywhere. I took it, then isolated both configs with CLAUDE_CONFIG_DIR and ran 18 headless trials on identical tasks. Output tokens dropped 21% and wall clock 20-29%, with zero counterexamples. But two of the rewritten rules never fired at all, and one result points the other way: the old config's most thorough run covered a strict superset of what the new one found. Why cheaper and better are separate questions.

prompt-engineeringclaude-code+4
claudeAug 5, 20266 min
3

DeepSeek V4 Pro vs Flash: I Ran 5 Hard Tests. Here's What 12x Gets You.

Here's the short version: **Pro is worth it for agent workloads. Flash has a hidden token-eating habit you won't notice until a long task eats your context.**

toolsAug 4, 20268 min
46

Half My openclaw Commands Ran, Half Didn't — It Looked Like a Permission Classifier, It Was launchd

Same machine, same user, same global config. Two Claude Code windows running the same CLI — one worked, one didn't. The obvious suspect was the permission classifier, which really does block commands. But the cause sat a layer down: the daemon's plist was installed and never loaded, so every gateway-bound subcommand died while purely local ones printed fine. That half-working shape is what sells the permission theory. Full trace, including the hypothesis I got wrong by misreading my own logs.

permissionstroubleshooting+4
developerAug 4, 20267 min
36

Running a 70B Model on a 4GB GPU: Hacker Dreams vs. Engineer Reality

70B on a single 4GB GPU, or small models at scale on the edge? AirLLM and Cloudflare show two roads to cheaper inference. A no-hype comparison of what each trades, and where each fits.

developerAug 4, 20264 min
46

Published by MagicTools