Usually not as written. A goal of zero critical vulnerabilities pushes teams to re-label severity, add blanket exceptions or stop scanning. A better goal is bounded exposure: critical findings that are reachable or exploited get fixed within an agreed window, and every exception has an owner and an expiry date.
What "critical" actually means
A critical label normally comes from a CVSS base score. FIRST, which maintains CVSS, states in its v4.0 user guide that base scores are designed to measure severity and should not be used alone to assess risk. It also asks that scores be written with a label showing which metric groups were used, such as CVSS-B for base only or CVSS-BTE when threat and environmental metrics are included.
So "zero criticals" can mean zero high-severity records in a database, regardless of whether any of them can be reached in your code or has been exploited anywhere.
How the goal goes wrong
- Severity shopping. Teams downgrade a score with a local override to hit the number.
- Exception sprawl. A blanket risk acceptance clears a hundred findings in one click.
- Scope shrinking. Archived or "temporary" repos drop out of the scan.
- Fix churn. Engineers upgrade a dependency to clear a label even when the vulnerable function is never called, and introduce regressions.
- Cliff effects. One new critical on a Friday turns a green status red, so people stop reporting early.
Each of these improves the number and leaves the risk where it was.
A better framing
Replace a state ("we have none") with a commitment ("we respond within a window"). The commitment is testable and cannot be met by hiding data.
| Weak goal | Stronger goal |
|---|---|
| Zero criticals open | Critical and reachable findings fixed or mitigated inside the agreed window |
| No exceptions | Every exception has an owner, a reason and an expiry |
| 100 percent scanned | Every production service scanned, with last scan age visible |
| Fewer findings | Falling time from detection to fix for the findings that matter |
Steps to move your team off the number
- Write the severity rule down: which score, which version, which metric groups.
- Add context fields to each finding: reachable or not, known exploited or not, exposed or internal.
- Define the response window per context. Reachable and exploited is the shortest.
- Require exceptions to carry an expiry, and report the count of expired exceptions.
- Show the old "criticals open" number as a secondary chart so nobody feels it vanished.
The EPSS model from FIRST can help with step 2. Its FAQ describes the score as an estimate of the likelihood that exploitation activity will be observed in the next 30 days, and it says plainly that it does not include context such as compensating controls. Use it as one input beside your own.
Where a zero target does make sense
A zero can be right for a narrow, well-defined class: known exploited vulnerabilities on internet-facing assets, or leaked credentials. A narrow zero has a clear definition and a clear action. A broad zero over a label does not.
Safeguard offers SBOM and dependency scanning, reachability analysis and policy gates. You can run a free scan at gold.safeguard.sh/scan.
Try it yourself
Click through it at your own pace, or open it full screen.
Watch how the list changes once reachability is taken into account, and ask which version of the list your goal should apply to.
Quick check
Does CVSS critical mean we are at critical risk?
No. FIRST describes base scores as severity, not risk. Risk needs threat and environment context.
What should replace a zero target?
A response window for findings that are reachable or exploited, plus owned, expiring exceptions.
Sources
Last reviewed: 19 October 2026.