In SCA, affected means your version is in a vulnerable range, reachable means your code can call the vulnerable function, exploitable means an attacker could use it in your setup, and exploited means attacks have been seen in the wild. Each step is a narrower claim, so each step should move a finding up or down your queue differently.
The ladder
| Term | Question it answers | Typical source |
|---|---|---|
| Affected | Is my version inside a published vulnerable range? | Advisory data such as OSV |
| Reachable | Can my code reach the vulnerable function? | Code analysis of your application |
| Exploitable | Could an attacker actually trigger it given my configuration and exposure? | Human or tool judgment with context |
| Exploited | Has anyone used it in real attacks? | A catalog such as CISA KEV |
Think of it as a funnel. Many findings are affected. Fewer are reachable. Fewer still are exploitable in your environment. A small number are known to be exploited.
Affected
This is what a plain SCA match gives you. The OSV format expresses it as ranges with introduced and fixed events, so a version is affected or not. It is a necessary starting point and a weak priority signal on its own.
Reachable
Reachability asks whether the vulnerable code path can be called from your application. A package may be affected but its vulnerable function may never be used. Reachability can be wrong, especially with dynamic code or reflection, so treat "not reachable" as a reasoned decision to record, not a guarantee.
Exploitable
This depends on context: the input an attacker controls, authentication, network exposure, and mitigating settings. Tools can help, but this step often needs a person, and a short written note is worth keeping.
Exploited
CISA describes the KEV catalog as the authoritative source of vulnerabilities exploited in the wild and says organizations should use it as an input to prioritization. FIRST's EPSS offers a related estimate of the likelihood of exploitation. Neither is a statement about your system, only about the vulnerability.
Putting it together
A workable ordering:
- Exploited and affected: look at these first.
- Affected and reachable: next.
- Affected, not reachable: schedule, and record why.
- Affected, no fix: apply mitigations and set a review date.
Write down which signal moved each item, so an auditor or colleague can follow the reasoning.
A worked example: three findings, three decisions
Your scan returns three findings in one service.
Finding one is a deserialization flaw in a library, and the CVE is listed in the known exploited catalog. The version you run is inside the affected range. Your code calls the library's deserialization function on data from an external API. Affected, reachable, likely exploitable, and exploited. This goes to the top of the queue with a short deadline.
Finding two is a denial of service flaw in a date parsing library. You are in the affected range. A call graph shows your code never calls the vulnerable parser. Affected, not reachable. You schedule the upgrade with the next maintenance, note the reasoning, and set a review date.
Finding three is a flaw in a test framework that only runs in continuous integration. Affected, and the package is development scope. You still upgrade, since CI systems hold credentials, but at normal priority.
The same CVSS score on all three would have told you nothing about this order.
Step by step: apply the ladder to your own queue
- Export your open findings with package, version, severity, and identifier.
- Mark each one that appears in the known exploited catalog. Put these first.
- For the rest, run or request reachability analysis and mark reachable and not reachable.
- For reachable ones, add a short note on exposure: internet facing, authenticated, internal only.
- Sort: exploited, then reachable and exposed, then reachable, then the rest.
- Set a target time for each tier and write it in your policy.
- Review the not reachable tier on a schedule, since code changes can make it reachable.
Why each term can mislead
Affected can overstate risk when the vulnerable function is unused. Reachable can understate risk when code uses reflection, plugins, or dynamic loading that analysis cannot see. Exploitable depends on assumptions about the environment that may be wrong. Exploited depends on what has been observed and reported, and absence from a list does not prove nothing is happening.
So treat each label as evidence with a confidence level, and make sure your tool shows what the label is based on.
What to ask a vendor
- Which of the four terms do you compute, and which do you import?
- For reachability, which languages, and how do you treat dynamic code?
- Can I see the evidence for a "not reachable" decision?
- Do you show known exploited status next to each finding?
- Can I override a label and record why?
Keep the reasoning
An auditor or customer may ask why you delayed a fix. A record saying "not reachable, call graph attached, review in 90 days" is far stronger than a silent deprioritization. Keep it with the finding, and include who decided and when.
Try it yourself
Click through it at your own pace, or open it full screen.
Step through a finding and note which question each screen answers on the ladder above.
Safeguard's reachability analysis is one of its GA capabilities, and a free scan shows findings for a repository.
Quick check
Is "not reachable" the same as "safe to ignore"?
No. It lowers urgency based on analysis that can be wrong. Record the reasoning and revisit it when the code changes.
Does a high EPSS score mean it is exploited?
No. EPSS estimates likelihood. KEV records actual exploitation evidence.
Which of the four terms should set my deadline?
Use exploited status first, then reachability and exposure, and use affected status as the baseline. Write the tiers and deadlines in your policy.
Sources
Last reviewed: 19 October 2026.