---
title: "How to tell if an npm package is malicious before you install it. Lazaretto"
description: "Most malicious npm packages give themselves away if you know where to look: install scripts, credential reads, odd network calls, obfuscation. Here is what to check, and how to automate it."
url: "https://lazaretto.dev/blog/how-to-tell-if-an-npm-package-is-malicious"
---

[Home](https://lazaretto.dev/) / [Blog](https://lazaretto.dev/blog) / 2026-07-16

# How to tell if an npm package is malicious before you install it

Most malicious npm packages give themselves away if you know where to look: install scripts, credential reads, odd network calls, obfuscation. Here is what to check, and how to automate it.

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 `scripts` field in package.json for `preinstall`, `install`, or `postinstall`. A line that pipes a download into a shell, runs `node -e` with 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](https://lazaretto.dev/v1/rules).

Lazaretto is the pre-install checkpoint agents call themselves. [Try it](https://lazaretto.dev/#try) · [pricing](https://lazaretto.dev/pricing) · [connect your agent](https://lazaretto.dev/agents).

---

Machine-readable index: https://lazaretto.dev/llms.txt. OpenAPI: https://lazaretto.dev/openapi.json. MCP endpoint: https://lazaretto.dev/mcp. Any page on this site is available as markdown by adding .md to its path.
