Skip to content
How-to · Supply Chain

How to Audit npm Dependencies for Supply-Chain Risk

A typical Node.js app pulls in hundreds of packages you never chose directly, and any one of them can ship a vulnerability, a typosquat or a malicious install script. This guide walks the full audit — from reading the lockfile to wiring up continuous monitoring — so you can judge, and keep judging, what your dependency tree is really running.

In plain words

Auditing npm dependencies for supply-chain risk means systematically checking every package your project installs — and PlayCISO has a free, browser-based npm scanner that runs the core checks for you. Work from the lockfile, scan for known vulnerabilities, look for typosquats and risky install scripts, weigh maintainer and provenance signals, pin versions with integrity hashes, and then keep monitoring.

The single highest-leverage habit is making the audit continuous: a new CVE or a quiet maintainer takeover is only dangerous if nobody notices it before you ship.

Step by step

  1. 1

    Start from the lockfile, not package.json

    package.json lists intent; package-lock.json (or the yarn/pnpm lockfile) lists what actually gets installed, including every transitive dependency and its resolved version. Audit the lockfile — it is the real bill of materials. Confirm it is committed, is in sync with package.json, and that CI installs with "npm ci" (which fails on drift) rather than "npm install", so nobody silently pulls a different tree than you reviewed.

  2. 2

    Scan for known vulnerabilities

    Run "npm audit" and cross-check against the GitHub Advisory Database and OSV so you are not relying on a single feed. Triage by whether the vulnerable code path is actually reachable and whether a fix exists, not just by the raw CVSS number. Record each finding with the package, version, advisory ID and your decision (upgrade, patch, accept with justification) so the audit is repeatable.

  3. 3

    Hunt for typosquats and dependency confusion

    Compare package names against the ones you meant to install — attackers register look-alikes (react-dom vs reactdom, lodash vs 1odash) and names matching your private internal packages to pull a public malicious version. Flag any dependency you do not recognise, any that was added recently, and any internal-looking name that resolves to the public registry. Scope your private packages and pin the registry to shut dependency-confusion down.

  4. 4

    Inspect install and lifecycle scripts

    preinstall, install and postinstall scripts run arbitrary code on your machine and in CI the moment a package is installed — a favourite foothold for supply-chain malware. List every package that declares a lifecycle script and read what it does. For CI and build boxes, install with "--ignore-scripts" by default and allow-list only the few packages that genuinely need a native build step.

  5. 5

    Check maintainer and provenance signals

    A package is only as trustworthy as who can publish it. Look at the number of maintainers, recent ownership or publisher changes, whether 2FA is enforced for publishing, how active the repo is, and whether releases carry npm provenance attestations (a signed link back to the source commit and CI build). A sudden new publisher on a long-dormant but widely-depended-on package is a classic takeover pattern worth pausing on.

  6. 6

    Pin versions and verify integrity hashes

    Pin to exact versions (avoid broad "^" ranges for anything sensitive) so an audited tree stays the tree you ship. The lockfile stores an "integrity" SHA-512 hash per package; "npm ci" verifies every download against it, so a tampered artifact on the wire or in a compromised mirror fails the install. Treat an integrity mismatch as an incident, not a flaky network.

  7. 7

    Make monitoring continuous

    A one-time audit ages out the moment a new advisory lands. Wire dependency and vulnerability checks into CI and a scheduled job so new CVEs, new typosquat matches and new maintainer changes are flagged automatically. Keep a generated SBOM alongside each release so that when the next big disclosure drops you can answer "are we affected?" in minutes instead of days.

Do it now — free, in your browser
Run the free npm supply-chain scanner

Paste a package name, package.json or lockfile and get known-vuln, typosquat, install-script and maintainer signals in your browser — the exact checks this guide describes.

Related

Frequently asked questions

Is "npm audit" enough on its own?

It is a good first pass but not a complete audit. npm audit only reports known vulnerabilities from its advisory feed and can both miss issues and over-report ones on code paths you never call. It tells you nothing about typosquats, malicious install scripts or suspicious maintainer changes, so pair it with the other checks in this guide.

Should I pin exact versions or use caret ranges?

For anything security-sensitive, pin exact versions and rely on the lockfile plus a scheduled update process. Caret ranges let a fresh install silently pull a newer, unreviewed version — convenient, but it means the tree you audited is not guaranteed to be the tree you ship. Controlled, reviewed bumps beat automatic drift.

What is npm provenance and does it matter?

Provenance is a signed attestation that links a published package back to the exact source commit and CI workflow that built it. When present, it raises confidence that the artifact on the registry matches public source and was not published from a maintainer laptop out of band. It is not yet universal, so treat it as a positive signal rather than a hard requirement.

Why block install scripts in CI?

preinstall and postinstall scripts execute arbitrary code during install, which makes them a common delivery mechanism for supply-chain malware and credential theft in build pipelines. Installing with --ignore-scripts by default and allow-listing only packages that truly need a native build step removes that automatic code-execution path.

How often should I re-run a dependency audit?

Continuously for the automated checks and on a human cadence for the judgment calls. Wire vulnerability and typosquat scanning into CI and a daily scheduled job, and have a person review new high-severity findings and maintainer changes at least weekly. A single quarterly audit leaves long windows where a new advisory goes unnoticed.

What is dependency confusion?

It is an attack where a package name that looks internal to your organisation is also registered on the public registry, and the resolver pulls the attacker-controlled public version instead of your private one. Defend against it by scoping private packages, pinning the registry for those scopes, and flagging any internal-looking name that resolves publicly.

🎉 New here? Use code WELCOME10 for 10% off any plan at checkout
How to Audit npm Dependencies for Supply-Chain Risk — PlayCISO · PlayCISO