Run a scanner against any real codebase and it hands you a hundred findings. Try to fix all hundred and you'll drown, fix none and you'll get breached, so the entire discipline is figuring out which few genuinely matter and dealing with those first. The teams that manage vulnerabilities well aren't fixing more than everyone else. They're triaging better and working a system instead of a panic.
Triage: does this even affect us?
Before a CVE earns any of your time, answer four questions. A scary-sounding vulnerability in a code path you never call is not your problem this week.
- Is the vulnerable function actually reachable from your code?
- Is the affected component exposed, or buried somewhere internal?
- Are there mitigating controls already in front of it?
- Is there a known, working exploit?
Modern SCA tools can tell you about reachability directly. If the vulnerable path isn't reachable, downgrade it and move on.
Prioritise: severity isn't the same as risk
The instinct is to sort by CVSS and start at the top. That instinct is wrong, because CVSS measures the vulnerability in the abstract, not the risk to you. A CVSS 9.8 in an internal tool used by three people matters less than a CVSS 6.5 in your payment API.
| Factor | High | Medium | Low |
|---|---|---|---|
| Exploitability | Public exploit | Proof of concept | Theoretical |
| Exposure | Internet-facing | Internal | Isolated |
| Impact | Customer data | Internal data | Cosmetic |
Two signals sharpen this further. EPSS estimates the probability a CVE will be exploited in the next 30 days, so a CVSS 7.0 at EPSS 0.95 outranks a CVSS 9.0 at EPSS 0.01. And the CISA KEV catalogue lists vulnerabilities known to be exploited in the wild; anything on it is a P1 regardless of its CVSS.
Remediate: upgrade, mitigate, or accept
You have three honest options, in order of preference:
- Upgrade. Almost always the right answer.
- Mitigate when you can't upgrade yet: a WAF rule, input validation, a network policy. Document it as temporary and give it a deadline, because temporary mitigations have a way of becoming permanent.
- Accept when the path genuinely isn't reachable and controls cover it. Write down who agreed, and put an expiry date on the acceptance so it gets revisited.
Run it as a system
Define SLAs by priority and actually track against them:
| Priority | SLA |
|---|---|
| P1 | 24 hours |
| P2 | 7 days |
| P3 | 30 days |
| P4 | 90 days |
Watch your mean time to remediate, your backlog age, your SLA compliance, and the ratio of new vulnerabilities to fixed ones. If new is consistently outrunning fixed, the backlog is growing no matter how busy you feel.
And the single highest-leverage habit, the one that quietly prevents most of this work: keep your dependencies current. Apply security patches same-day, patch versions weekly, minor versions every couple of weeks. A codebase that's already up to date has far fewer of those hundred findings to begin with.
