Does npm audit detect malicious packages?
It is the reasonable assumption - you ran npm audit, it said "found 0 vulnerabilities", so your dependencies are fine. Unfortunately npm audit is answering a narrower question than most people think, and the gap is exactly where supply-chain attacks live.
Updated · Precursor Security
What npm audit actually checks
npm audit compares your dependency tree against the GitHub Advisory Database and reports entries that match. That database is overwhelmingly a record of vulnerabilities - accidental security bugs in legitimate, well-intentioned packages. A prototype pollution bug in a utility library, a ReDoS in a parser, a path traversal in a static file server.
That is genuinely useful, and you should keep running it. But a vulnerability is a mistake in code that is supposed to be there. A supply-chain attack is code that was never supposed to be there at all, and the two get handled very differently.
Why malware slips through the gap
Three things work against you.
Takedown removes the evidence. When a malicious package is discovered, the registry usually removes or replaces it within hours. That is the right call for stopping the spread, but it means the package no longer exists to be looked up. Your lockfile still pins evil-pkg@1.2.3; the registry no longer has a record to match against; the audit comes back clean.
Advisories lag, and sometimes never arrive. A CWE-506 "embedded malicious code" advisory may be published days after the package was pulled, or not at all for smaller campaigns. Meanwhile the compromised version has been sitting in your lockfile the whole time.
The damage is already done. Most of these packages execute during npm install via a postinstall hook. By the time any tool tells you about it, the payload has already run with your environment variables in scope. Detection after the fact is about knowing what to rotate, not about prevention.
What to run instead - or rather, as well
There is no single tool that covers this. A reasonable layered setup:
- Keep
npm auditin CI. It catches real vulnerabilities and costs nothing. - Match your lockfile against known-malicious versions. This is the specific gap above, and it is what this site does - we keep the compromised package–version pairs even after the registry has removed them, so a takedown does not erase your ability to check.
- Disable install scripts where you can.
npm config set ignore-scripts trueblocks the most common execution path. It breaks packages that genuinely need a build step, so it is easier to adopt in CI than locally. - Pin and commit your lockfile. Without one, every fresh install re-resolves your ranges against whatever is on the registry today.
- Keep install-time network egress narrow in CI. Most payloads need to reach a C2 host to be useful.
A worked example
Take a typosquat published against a popular HTTP client. The sequence usually runs:
- Attacker publishes
ax1os@1.0.0with apostinstallscript. - Someone typos it, or an LLM-generated snippet suggests it, and it lands in a lockfile.
npm installruns the hook; environment variables are exfiltrated.- A researcher reports it; npm removes the package within a few hours.
- You run
npm auditthe following week. Nothing to report - the package is gone.
Steps 3 and 5 are the whole problem. The compromise is real and still pinned in your lockfile, but the lookup that would have found it no longer resolves.
Common questions
- Is
npm auditworth running at all? - Yes. It is good at what it does - finding known vulnerabilities in legitimate packages - and that is a real category of risk. The mistake is reading "0 vulnerabilities" as "no malicious code", which is a different claim it was never making.
- Do
yarn auditandpnpm auditbehave differently? - No, in the way that matters. They query advisory data for known vulnerabilities and inherit the same blind spot around removed malicious packages.
- Would Dependabot or Renovate have caught it?
- They keep you on current versions, which genuinely reduces exposure to old vulnerable releases. But they are driven by the same advisory data, and automated upgrades can move you onto a compromised release if a maintainer account has just been taken over.