Safeguard
Application Security

Reducing false positives in SAST and SCA tools

NIST benchmark data puts some SAST false-positive rates near 78%. Reachability analysis and contextual triage are how teams cut that noise without missing real risk.

Safeguard Research Team
Research
6 min read

Static analysis has a credibility problem, and the numbers back it up. NIST's SAMATE research, evaluated against the OWASP Benchmark test suite, found SAST tool false-positive rates as high as 78% on Java codebases, while separate OWASP Benchmark runs measured DAST false-positive rates around 82% for some configurations. The spread across individual tools is just as wide: SonarQube has reported false-positive rates as low as 1% on the OWASP Benchmark, while a 2024 Tolly Report found a Checkmarx configuration producing a 36% false-positive rate on a separate set of benchmark applications — different test suites, but the same lesson: the ceiling isn't the technology, it's the tuning. Software composition analysis (SCA) has its own version of this problem: a dependency scan flags every CVE in every installed package, whether or not your application ever calls the vulnerable function. The result, across both disciplines, is the same failure mode: security teams drowning in tickets, developers learning to ignore the scanner, and real vulnerabilities buried in the noise. This post covers what actually moves the false-positive needle — reachability analysis, exploit-likelihood scoring, and contextual triage — and what those techniques can and can't fix.

Why do SAST and SCA tools produce so many false positives in the first place?

They produce noise because both techniques default to flagging possibility rather than probability. A SAST engine pattern-matches or taint-tracks dangerous constructs in source code without necessarily knowing whether an attacker can drive input to that line at runtime; an SCA engine matches your lockfile against a CVE database without checking whether your code imports, let alone calls, the vulnerable function. Industry guidance from vendors like Mend.io makes the same point: out-of-the-box SAST and SCA configurations tend to run hot on false positives, and tuning ruleset strictness and dependency depth is what brings that rate down — the more transitive dependencies a scanner walks, the more theoretical findings it surfaces. Neither failure mode is a bug; it's the direct consequence of designing for recall (don't miss a vulnerability) over precision (don't cry wolf), which is defensible in isolation but unsustainable once a team is running the same tool across hundreds of repositories.

How does reachability analysis cut noise without dropping real risk?

Reachability analysis adds proof, not just presence: it builds a call graph from your application's entry points and checks whether execution can actually reach a vulnerable function, rather than merely confirming the vulnerable package is installed. Independent studies of open-source reachability tooling have documented reductions in the same range: one empirical analysis of automated call-reachability analysis across popular Go projects confirmed only a fraction of reported vulnerabilities as actually present, cutting false positives by roughly three-quarters overall and by as much as 90% on individual projects — a concrete illustration that layering a reachability pass on top of raw findings, rather than trusting a single engine's output, is where the bulk of the improvement comes from. Safeguard's own reachability engine documents three reachability modes — static call-graph analysis, dynamic runtime tracing, and configuration-based reachability (e.g., parsing Spring bean definitions or Next.js route files) — and classifies each CVE as reachable, conditionally reachable, unreachable, or unknown, with unknown findings (reflection, eval, dynamic dispatch) deliberately kept visible rather than suppressed.

Why isn't CVSS severity alone enough to prioritize findings?

CVSS measures theoretical severity — what happens if a vulnerability is exploited — not the probability that it will be, and conflating the two is a major source of misprioritized backlogs. That gap is exactly why FIRST.org, the standards body behind CVSS, built EPSS (Exploit Prediction Scoring System) as a companion score: a data-driven model — first proposed in 2019 and in daily production since 2021 — that outputs a daily-updated 0–1 probability estimating the likelihood a given CVE will be exploited in the wild within the next 30 days. CISA's Known Exploited Vulnerabilities (KEV) catalog adds a third, binary signal — confirmed real-world exploitation, no probability involved — that security teams widely treat as an automatic escalation trigger regardless of CVSS score. A critical-CVSS finding with near-zero EPSS and no KEV listing is a very different ticket than a medium-CVSS finding that's actively being exploited and sitting on KEV; teams that only sort by CVSS treat these identically, which is its own quiet source of false urgency.

What role does runtime and business context play in triage?

Runtime and business context determine whether a technically-reachable finding deserves attention this sprint or next quarter. A vulnerable code path that's reachable in principle but only executes inside a dev-only Docker Compose file, behind a disabled feature flag, or in an internal air-gapped service carries a different real-world risk than the identical finding sitting in an internet-facing production API handling customer PII. Contextual triage layers in signals like environment (production vs. staging vs. dev), exposure (internet-facing vs. internal), data classification, and policy-defined business criticality — for example, whether an asset falls under PCI, HIPAA, or FedRAMP scope. This is also where cross-scanner deduplication earns its keep: when a SAST and an SCA engine both flag the same underlying component, correlating them into one finding instead of two separate tickets is a distinct, complementary source of noise reduction from reachability itself, and it should never touch malware or secrets findings, which need to stay fully visible regardless of dedup logic.

Where does reachability analysis fall short, and what fills the gap?

Reachability is not a silver bullet, and vendors that market it as one set false expectations. It's weakest against dynamically dispatched code — reflection, eval, or plugin-style loading — where a static call graph genuinely cannot determine whether a path executes, and against data-driven vulnerabilities where a function is technically unreachable by static analysis but still processes attacker-controlled input once triggered by a specific payload. The correct response to that uncertainty is conservative defaulting: mark ambiguous findings as "unknown" rather than "unreachable," and keep them in the queue rather than auto-closing them. This is also why layered signals matter more than any single technique — EPSS, KEV, and runtime observation (recording which modules actually execute in production workloads) catch cases that pure static reachability analysis misses on its own, and none of the four signals should be trusted as a sole gatekeeper for suppressing a finding.

How does Safeguard put these signals into practice?

Safeguard's prioritization engine combines all four signals discussed above — reachability, EPSS/KEV exploitability, runtime context, and business context — into a single ranked score, and reports aggregate noise reduction of 60–80% off the urgent queue across customer tenants without hiding the underlying findings. AutoTriage handles the complementary problem of cross-scanner duplication, correlating overlapping SAST and SCA results into one finding with a measured, auditable reduction percentage, while explicitly guaranteeing that malware and secrets findings are never suppressed regardless of dedup logic. The goal isn't a smaller number for its own sake — it's a backlog where a security engineer can trust that what's on top is actually worth fixing this week, and what's filtered out was filtered for a documented, inspectable reason rather than disappearing silently.

Never miss an update

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