🚨USE THIS GUIDE TO PROTECT YOUR COMPUTER FROM NPM HACKS THAT STEAL EVERYTHING IN ONE INSTALL
TanStack, a code library used in millions of web apps, got hacked on Monday
one install steal every password, key, and credential on your computer
this is far not the first hack this month and definitely just the beginning
Here's how to protect your machine:
[ 1. lock down npm with a 7-day cooldown ]:
open ~/.npmrc. keep all existing lines (auth tokens, registry config). append:
"""
min-release-age=7
minimum-release-age=10080
save-exact=true
"""
this makes npm refuse any package version published in the last 7 days. attack windows are usually under 24 hours, you skip them entirely
[ 2. same cooldown for bun ]:
open ~/.bunfig.toml (create if missing). append:
"""
[install]
minimumReleaseAge = 604800
"""
7 days in seconds, same protection in bun's config format
[ 3. pin every npm dependency in your projects ]:
open package.json. strip every ^ and ~ from versions under:
- dependencies
- devDependencies
- peerDependencies
exact versions only. commit your lockfile (bun.lock / package-lock.json / pnpm-lock.yaml) to git so the resolved tree is frozen
[ 4. same discipline for python ]:
if you use uv (the modern default): commit uv.lock, run `uv sync` to restore
if you use pip: requirements.txt with pinned versions, run `pip install --require-hashes -r requirements.txt`
if you use poetry: commit poetry.lock, use `poetry install --no-update`
never trust `>=` or `~=` ranges in production projects
[ 5. pin GitHub Actions to commit SHAs ]:
stop using `actions/checkout
@v4`. switch to:
```yaml
uses: actions/checkout
@b4ffde65f46336ab88eb53be808477a3936bae11
```
every third-party action runs in your CI with access to repo secrets. pinning the SHA means a compromised maintainer cannot push malicious code into your pipeline
[ 6. audit your IDE extensions ]:
Cursor, VSCode, Windsurf, every extension is code running with full access to your filesystem, clipboard, and open files
- review installed extensions monthly
- remove anything you haven't actively used in 30 days
- check the publisher, install count, last update, GitHub source before installing
- never install extensions that ask for permissions they shouldn't need
[ 7. lock down API tokens and credentials ]:
- never commit .env to git (add to .gitignore on every project, no exceptions)
- use minimum-scope tokens: one repo, one bucket, one workspace
- rotate API keys every 90 days, force expiry on critical ones
- separate tokens by environment (dev / staging / prod)
- enable 2FA on every developer account: GitHub, npm, PyPI, Cloudflare, AWS, OpenAI, Anthropic
- never paste secrets into Claude / ChatGPT / any AI chat, they're logged
[ 8. set up continuous monitoring ]:
- enable Dependabot alerts on every repo (free, takes 2 minutes)
- install or Snyk for live vulnerability scanning
- subscribe to the npm and PyPI security advisory feeds
- follow
@snyksec,
@socketsecurity,
@stepsecurity for early warnings
[ 9. how to detect if you got the TanStack payload ]:
if you installed any
@tanstack/* package between 19:20 and 19:30 UTC on Monday, May 11, treat the host as compromised
the detection signature: a malicious manifest contains
"optionalDependencies": {
"
@tanstack/setup": "github:tanstack/router#
79ac49ee#..."
}
any version with this entry is compromised. the payload is delivered via the git-resolved optionalDependency, whose prepare script runs router_init.js (~2.3 MB, smuggled into the tarball root)
how to check fast:
- search your lockfile for `
@tanstack/setup` references
- search node_modules for any `router_init.js` file
- if either shows up, jump to section 10 immediately
future attacks will use the same trick: malicious code hidden in optionalDependencies or postinstall/prepare scripts. add `grep -r "postinstall\|prepare" node_modules/*/package.json | grep -iE "curl|wget|eval|base64"` to your weekly audit routine
[ 10. emergency response if you're already compromised ]:
ran an install during a suspected attack window? do this in this exact order:
- rotate every cloud credential: AWS, GCP, Kubernetes service accounts, Vault tokens
- rotate GitHub personal access tokens, OAuth tokens, SSH keys
- revoke active sessions on GitHub, npm, PyPI, all cloud providers
- audit AWS / GCP / Kubernetes / Vault audit logs for the last several hours, look for unauthorized API calls
- pin to the last known-good version of every
@tanstack package and reinstall from a clean lockfile
- check ~/.npm, ~/.config, browser cookie stores for tampered files
- wipe ~/.bash_history, ~/.zsh_history, local AI chat logs that might have secrets
- if you ran the install as root or with sudo: nuke the machine, reinstall from scratch, restore code from git only
[ why this matters right now ]:
attack chains in supply chain hacks usually only last a few hours before the malicious package gets caught and yanked. during those hours, every developer running `npm install` becomes a victim
worse: npm couldn't even UNPUBLISH most of the TanStack malicious versions because of third-party dependencies. the registry's own safeguards are part of the problem. you can't rely on the platform, you have to protect yourself
the patterns from the last 18 months:
- npm: TanStack on May 11 (42 packages, AWS/GCP/Vault credentials), Shai-Hulud worm hit Nx packages, chalk/debug/ansi-styles worm hit qix maintainer
- GitHub Actions: tj-actions/changed-files compromise exposed thousands of repos' secrets
- PyPI: ongoing typosquatting campaigns targeting AI/ML packages
- IDE extensions: VSCode marketplace caught hosting credential stealers
the frequency is rising because the payoff is massive
one compromised package lands on millions of machines in hours
if you don't lock this down tonight, you're exposed to the next one. and there will be one
30 minutes tonight, or wait for the next attack to clean out your machine
Full TanStack breakdown: