Most malicious npm packages give themselves away if you know where to look. The trouble
is that nobody looks. npm install runs hundreds of times a day and reading every
dependency by hand is not realistic. Here is what actually matters, and how to stop doing it by hand.
The tells
A package that is up to something usually does at least one of these:
- Runs code the moment you install. Check the
scriptsfield in package.json forpreinstall,install, orpostinstall. A line that pipes a download into a shell, runsnode -ewith inline code, or base64-decodes something is a flag. - Reads files it has no reason to touch.
~/.ssh/id_rsa,~/.aws/credentials, browser profile paths, environment variables full of tokens. - Sends data out. A hardcoded IP or an odd domain next to an HTTP call, DNS lookups built from command output, a fetch to a pastebin.
- Hides what it does. Long base64 or hex blobs, dynamic
eval, or a minified bundle shipped next to readable source.
Automate it
Reading for all of that by hand does not scale. Lazaretto does it for you. Point it at a package and it pulls the files into a sandbox, never runs them, and checks for exactly these patterns plus a match against known-bad hashes. You get a verdict and the exact line that tripped it.
curl -s https://lazaretto.dev/v1/known-bad/<sha256> # free
curl -s -X POST https://lazaretto.dev/v1/scan -H 'content-type: application/json' \
-d '{"target":{"type":"npm_package","ref":"some-pkg@1.0.0"},"depth":"full"}'
The known-bad lookup is free. A full scan is a few cents over x402 or with a prepaid key. See the rule catalog.
Lazaretto is the pre-install checkpoint agents call themselves. Try it · pricing · connect your agent.