Install script safety
Everyday A package can run code on your machine the moment you install it, through scripts likepreinstall.js. That code runs as you, so it can read your tokens and files.What actually protects you
| Layer | Stops | Doesn't stop |
|---|---|---|
| Blocking install scripts | The most common attack: code running at install | Malicious code you later import and run |
| Release delay | Freshly hijacked versions, which are often caught within days | Long-running compromises |
| Secrets outside plain files | Theft of tokens from .env and .npmrc | Misuse of a logged-in tool |
| Containers or a VM | Damage reaching your real files | Anything you mount or share with them |
| Antivirus | Some known and suspicious behavior | Plenty of scripts that look like normal Node |
| GitHub Pro | Bad pushes to protected branches on private repos | Anything on your PC: the attack happens before GitHub is involved |
npm vs pnpm
Tested with a harmless local package whose preinstall wrote a marker file:
| Tool | Did the script run? |
|---|---|
| npm 11.20 | Yes. It warned, but the script had already run |
| pnpm 12.16 | No. Ignored build scripts, with pnpm approve-builds to allow specific packages |
Harden npm
npm config set ignore-scripts true
npm config set min-release-age 7min-release-age counts days. Packages with native parts may need their scripts run by hand after this. Lifecycle hooks in your own package.json are also skipped.
Harden pnpm
Add a delay in pnpm-workspace.yaml. The value is in minutes, so this is 7 days:
minimumReleaseAge: 10080Keep secrets out of files
Reference secrets instead of storing them, then inject them at run time:
# .env.1p: references only, not values
API_KEY=op://vault/item/fieldop run --env-file .env.1p -- npm run devUse narrowly scoped, short-lived npm tokens. Never leave old ones in backups.
Lock down your Git account
- Use a passkey or security key for 2FA.
- Remove tokens and apps you no longer use.
- Protect the branches that matter, and require signed commits where you can.
- Turn on Dependabot alerts.
Untrusted repos
Don't open them directly on your PC, and don't treat a WSL distro as a sandbox. Use Windows Sandbox, a VM, or a container with only that repo mounted.
When antivirus flags your dev tools
Behavior detections, such as Kaspersky's PDM:Exploit.Win32.Generic, can flag legitimate tools that launch many shells or inspect the system. Don't assume it's a false alarm, and don't just turn protection off.
- Check the signature of the flagged program:powershell
Get-AuthenticodeSignature "C:\path\to\tool.exe" | Format-List Status, SignerCertificateStatusshould beValid, with the expected publisher. If not, stop and reinstall from the official source. - Add the narrowest exception that works: one program and one detection name. In Kaspersky, that's Settings > Security settings > Threats and Exclusions > Manage exclusions.
- Only if that fails, make that one program a trusted application, ticking only "Do not monitor application activity".
- Report the false alarm to the vendor.
Never whitelist powershell.exe, cmd.exe, node.exe, your projects folder or your user folder, because attackers run through those too. Avoid "Do not monitor child application activity", which can also stop monitoring install scripts started by that program.