Evidence-backed VEX · deep dive

Proof-of-exploitability vs. reachability analysis

These two terms get used interchangeably, and they are not the same thing. Reachability asks whether vulnerable code can be reached; proof-of-exploitability asks whether reaching it does any harm. The gap between them is exactly where false positives — and defensible not_affected decisions — live.

Updated 7 Jul 2026·~6 min read·For product security engineers

"Is it reachable?" and "is it exploitable?" sound like the same question asked twice. They aren't, and conflating them is one of the most common ways a vulnerability programme either drowns in false positives or waves through something it shouldn't.

Two different questions

Reachability and exploitability sit at different depths. Reachability is a question about your call graph: can execution get from an entry point to the vulnerable function? Exploitability is a question about consequences: if it gets there, can an attacker actually drive it into the vulnerable state and get the harmful outcome? The first is necessary for the second, but it is not the same as the second.

What reachability tells you

Static reachability analysis walks the call graph and asks whether the vulnerable code is present and callable along a path your product exercises. It's cheap, it scales, and it resolves a large share of matched CVEs immediately: anything genuinely unreachable is not_affected, backed by the vulnerable_code_not_in_execute_path justification. For the noise that dominates a real SBOM — dependencies pulled in but never invoked — reachability is the right, efficient answer.

Its limit is that it reasons about whether code runs, not what happens when it does. Faced with a reachable path, static analysis has to make a conservative assumption, and the conservative assumption is "reachable, therefore potentially affected." That's safe, but it puts the hardest cases straight back on your desk.

What exploitation proof adds

Proof-of-exploitability takes a reachable candidate and attempts the exploit in your product's context. It answers the question reachability had to leave open:

  • If the attempt succeeds, you have a captured proof artifact and an unambiguous affected.
  • If it fails — input validation blocks the payload, a config flag disables the feature, the sink can't be controlled — that failure is itself evidence for a not_affected, under the vulnerable_code_cannot_be_controlled_by_adversary justification.

Either way you get a determination grounded in a demonstrated result, not an inference.

The gap between them

The interesting cases live in the gap: reachable but not exploitable. These are common — a vulnerable parser that only ever sees trusted input, a CVE whose exploitable branch your configuration never enters. Reachability flags them; only an exploitation attempt clears them with confidence.

Reachable is not the same as exploitable. The difference is a false positive you either carry forever or resolve with evidence.

This is why the sensible design is two stages, not one: cheap reachability first to clear the bulk, exploitation proof second on the reachable, actively-exploited candidates that actually warrant it. That ordering is what keeps the cost bounded while still resolving the cases that matter.

Why the CRA cares about the difference

Under the CRA you report actively exploited vulnerabilities that affect your product, and you justify the ones you don't report. A not_affected resting on "we think it's not reachable" is weaker than one resting on "the vulnerable path isn't reached, and when we forced it, the exploit didn't fire." When a market-surveillance authority asks why a KEV-listed vulnerability in your dependency wasn't reported, the depth of your evidence is the whole answer. The pillar — evidence-backed VEX — puts this in the context of the full determination.

Frequently asked

Is reachability analysis the same as proof-of-exploitability?

No. Reachability analysis determines whether the vulnerable code can be reached from an entry point in your product. Proof-of-exploitability goes further and attempts to actually trigger the vulnerable condition. Code can be reachable yet not exploitable — because of input validation, configuration, or existing mitigations.

Do I need exploitation proof if I already have reachability?

Reachability is a strong, cheap first filter and resolves many cases on its own — anything unreachable is safely not_affected. Exploitation proof matters for the reachable candidates a regulator is most likely to ask about, especially those under active exploitation, where "reachable" alone tends to be read as "affected".

Is static reachability enough for a not_affected VEX under the CRA?

Often, yes — a not_affected justified by "vulnerable code not in execute path" is a legitimate, evidence-backed VEX justification. Where reachability can only guess, an exploitation attempt turns the guess into a demonstrated result you can defend.

Design partners

See both gates run on your product.

Bring an SBOM. We’ll show you reachability and, where it counts, exploitation proof — with the artifact attached to each determination.