npm audit tells you about 47 high-severity vulnerabilities. You patch nothing and ship anyway. Was that negligent, or was it correct? Usually the second. Here's how to tell which, repeatably.
Severity is not exploitability
A CVSS score is a worst-case rating based on the library in isolation. It doesn't know:
- Whether your app calls the vulnerable function.
- Whether the vulnerable code path is reachable at runtime.
- Whether the input that triggers it can reach the library from an attacker.
A "critical" advisory in a library you only use in a build script at CI time is less urgent than a "medium" advisory in your request-handling path. The severity number doesn't encode that.
The three-question triage
For any advisory I look at, I answer three questions in order:
- Is the package in my runtime bundle, or only a build/dev dependency? Dev-only means lower urgency — the attack surface is your build machine, not production.
- Does my code actually call the affected API?
npm auditflags the package. Whether you call the vulnerable function is a separate question answered by grep. - Can untrusted input reach that call path? If the vulnerable function only runs on data you control, the practical exploitability drops sharply.
Most advisories die at step 1 or 2. The ones that survive all three are the ones to patch urgently.
Tooling that actually helps
npm audit --production hides dev-only advisories immediately. That alone cuts the noise by half for most projects.
For deeper analysis, tools like Socket and Snyk do reachability analysis — they check whether the vulnerable function is called from your code, not just whether the package is installed. This is the signal that matters.
When to patch fast anyway
Three cases override the triage:
- Supply-chain compromise (malicious code published, not just a bug): patch immediately regardless of reachability.
- Remote code execution in a package that processes user input (template engines, parsers, serializers): patch immediately.
- Regulated environments: compliance often demands patching on severity alone. Document the triage but patch anyway.
Everything else gets batched into the next weekly dependency PR.
The failure mode to avoid
Patching reflexively on every alert trains you to ignore alerts. The triage exists so that when a real one lands, you're still paying attention.