Safeguard
Security Guides•

How to test a vendor's reachability claims in a proof of concept

Reachability analysis should cut noise without hiding risk. Plant known cases in a pilot repo and check what each tool marks reachable or unreachable.

Safeguard Security Team
3 min read

Test reachability by planting cases whose answer you already know: a vulnerable function that is called, one that is not, and one that is only called through reflection or a framework. A good tool gets the clear cases right and says "unknown" for the hard one instead of guessing.

What reachability is claiming

Reachability analysis asks whether your code can actually call the vulnerable part of a dependency. If it cannot, the finding is lower priority. If it can, the finding is urgent. The claim is attractive because it can remove a large share of alerts. It is also easy to overstate, because call graphs are hard in dynamic languages.

Build the test set

Pick a small repo and add dependencies with known advisories that name a specific function. Then create four situations:

  1. Direct call. Your code calls the vulnerable function. Expected: reachable.
  2. Imported, never called. The package is imported but the function is not used. Expected: unreachable.
  3. Transitive call. A package you use calls a vulnerable function in one of its dependencies. Expected: reachable through the chain.
  4. Dynamic call. The function is invoked through reflection, dependency injection or a string lookup. Expected: unknown or reachable, not unreachable.

Record the right answer for each before running any tool. Keep the key away from vendor staff.

Score what you see

For every tool, make a table of tool answer against expected answer.

  • A false "unreachable" on a case that is reachable is the dangerous error. Weight it heavily.
  • A false "reachable" costs time but is safe.
  • "Unknown" on hard cases is acceptable and honest.

Ask also whether the tool shows the path it found. A call path you can read lets a developer verify the claim in minutes. A bare label forces trust.

Check the edges

  • Does it work across the languages you ship, or only one?
  • Does it handle your build setup, such as a monorepo or a generated code folder?
  • How long does it add to a scan?
  • What happens with a dependency that has no function level advisory data? The honest answer is that function level reachability cannot apply and the tool should say so.
  • Does it keep suppressed findings visible for audit, with the reason?

Try it yourself

Click through it at your own pace, or open it full screen.

Watch how the finding list changes once reachability is applied, then ask yourself what evidence you would need to trust each removal.

Treat the reduction number carefully

A vendor may quote a percentage of alerts removed. That figure depends on the code base it was measured on. Your own pilot is the only number that counts. Count the findings before and after on the same repos, and spot check a sample of the removed ones by hand. For a method, see measuring false positives in a pilot.

Safeguard offers reachability analysis alongside dependency scanning, and you can try a free scan on your own project to see how the output reads.

Quick check

Is unreachable the same as safe?

No. It means the vulnerable code is not called today. A code change can make it reachable later, so keep monitoring.

How many planted cases are enough?

Ten to twenty across the four situations gives a useful signal without turning the pilot into a research project.

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.