← All articles

When everything is “critical,” nothing is: prioritizing vulnerabilities by real risk

July 12, 2026 · Wilson Santos · updated July 26, 2026

Run any scanner across a real system and you will get the same shape of result, a wall of findings, most of them stamped "high" or "critical." Those labels come from CVSS, the Common Vulnerability Scoring System, is the industry-standard scale from 0 to 10 that rates how dangerous a flaw is on its own terms. It did its job: it told you how severe each issue is in the abstract. What it did not tell you is the only thing you need on Monday morning: which one do I fix first?

Severity is not priority. And the gap between them is where security programs quietly fail.

Why severity can't rank your work#

CVSS scores a vulnerability in isolation, as if every place it appears were identical. But the same CVE is not the same risk everywhere:

  • On an internet-facing service with no auth, it's a live attack path.
  • On an internal tool three network hops away, behind a policy, it's a someday-maybe.
  • On the component that, if it falls over, takes the whole platform with it, it's an emergency, regardless of the score.

Feed all of that into one severity number and you get the two failure modes every team knows: either you chase everything marked critical and burn out, or you stop believing the labels and route around the gate. Both end in the same place, with the urgent thing sitting in a backlog next to a hundred things that look exactly as scary.

The two questions a scanner can't answer#

To rank findings you need two pieces of context that no scanner can compute, because they aren't properties of the code:

  1. How exposed is the thing this lives in? Reachable from the internet, or namespace-scoped behind a network policy?
  2. How much does the business care if it breaks? Platform-wide outage, or a dev tool nobody would notice for a week?

The first is about likelihood, meaning how reachable the weakness is, and the second is about impact, meaning what it costs if it goes wrong. Real risk is the product of the two, layered on top of raw severity. A scanner sees none of it.

But your app description does#

You already know this context. You know which services face the world and which are buried. You know which ones are load-bearing. That knowledge is stable, small, and exactly the kind of thing Draugr already captures in the app descriptor.

So it becomes two more attributes on a component you already describe, its exposure and its business criticality, and prioritization falls out of the description you wrote once.

components:
  - name: ingress-gateway
    exposure: public          # reachable from the internet
    criticality: critical     # failure = platform-wide outage
  - name: dev-dashboard
    exposure: restricted      # internal, network-scoped
    criticality: supporting   # nobody pages at 3am for this
The same CVE, two priorities A single finding, CVE-2023-30861 at high severity, is ranked separately for each component that carries it. On ingress-gateway, which is public and business-critical, it is P1 and gets fixed now. On dev-dashboard, which is restricted and supporting, the same finding is P3 and goes to the backlog. CVE-2023-30861 severity: high, one finding, one score ingress-gateway exposure: public criticality: critical dev-dashboard exposure: restricted criticality: supporting P1 act now P3 backlog
Same finding, same severity, two answers, because the components differ.

Now the same CVE resolves two different ways, so on the gateway it is fix-now and top of the list. On the dashboard it is track-and-move-on. Severity was identical and priority was not, because priority combines the finding's severity with the component's exposure and criticality into a single, ordered answer.

The third input, whether anyone is exploiting it#

Exposure and criticality describe your side. There's one more signal, and it comes from the world: exploitability.

A CVE on CISA's KEV catalog is known to be exploited in the wild, not theoretically exploitable, and used against real systems. That escalates a finding whatever its CVSS score says, because a modest score being exploited today outranks a 9.8 nobody has ever weaponized. A high EPSS probability, the likelihood a CVE gets exploited in the next thirty days, bumps a finding up a band on the same logic.

Both are opt-in and read from feeds you provide, so the ranking stays reproducible, because the same inputs give the same order, and you can point at where each escalation came from.

What that changes#

For a developer, the output stops being a 400-row dashboard and becomes a short list: these three, in this order, today. Clear action, not triage archeology.

For the business, it is consistent and defensible, because the same rules apply to every service, so "what is our real exposure right now?" has an answer, and the urgent gets a faster response because it's no longer buried under look-alikes.

For your coding assistant, it's the difference between a list and an order. Point one at Draugr and it answers from the same ranking your pipeline uses. A scanner can hand an assistant a pile of findings, but only your description can tell it which one to fix.

This is what Draugr does. Not another dashboard that shows you more, but a gate that tells you less, being the few things that matter, ranked by your own context. Describe your app, and the description doesn't just decide which scanners run. It decides what you fix first.