In security, the bug you miss costs more than the alert you dismiss

Why we optimise a code scanner for recall first, how we build for it, and how our recall measures on three codebases today.

Vybscan engineering Sep 23, 2026 5 min read
โ† Back to Blog

Every code scanner is judged on two numbers. Precision asks how much of what it reports is real. Recall asks how much of what is real it reports. You can't maximise both, and every scanner makes a choice about which to favour, whether its makers say so or not.

We favour recall. Here is why, what that means for how we build, and what our recall measures today.

Why recall matters more for security

The two errors do not cost the same

A false positive costs an engineer a few minutes: read the finding, see that it's not real, dismiss it. A false negative costs whatever the vulnerability costs once someone else finds it. That might be a breach, a disclosure, an incident review or a customer's data. One error is measured in minutes, the other in months.

A false positive

Shows up on the page. Someone reads it, judges it and closes it. The cost is visible, bounded and paid once.

A false negative

Shows up nowhere. The report reads clean, the code ships, and the cost arrives later, on someone else's schedule.

An attacker only needs one

Defenders have to close every door. Attackers need to find one open. A scanner that reports ninety of a hundred real issues perfectly still leaves ten doors open, and nobody knows which ten. So recall sets the ceiling on what a scan can protect.

A clean report is a claim

When a scan reports nothing, teams read that as "safe to ship". That silence is only worth as much as the scanner's recall. High precision with low recall produces the most dangerous report there is: short, tidy and wrong.

Precision still matters, as the price of being read

This is not an argument for noisy tools. A page where half the rows are wrong teaches people to stop reading, and then even its true findings are missed. That's a recall failure too, just a human one. So we treat precision as a constraint: keep the list trustworthy enough that people act on it, and within that, find everything.

Precision decides whether people read the report.
Recall decides whether the report was worth reading.

How we build for recall

No single technique finds every class of vulnerability. Each has blind spots the others do not share. So we run several independent engines over the same code and combine what they find.

  • Deterministic analysis of every file. Application code, templates, scripts, infrastructure definitions and CI pipelines all get the same rules. Rules never get tired and never skip a file, so they are the floor under everything else.
  • AI reasoning over the code most likely to matter. A model reads prioritised code the way a reviewer would. It follows data across functions and explains each claim, so it catches flaws that span functions, which rules miss.
  • Endpoint-level analysis of business rules. Many serious flaws involve no dangerous function at all: a record anyone can read, a benefit that can be claimed twice, a price the client chooses. We check each endpoint against the rules it should enforce, not just the functions it calls.
  • Verification against the code. Each finding is checked against the source before it is presented. That keeps precision high enough for the recall to matter.

Every miss we find, in a benchmark or a customer codebase, is treated as a defect in the scanner. We work out why it was missed, fix the whole class rather than the one instance, and test the fix across other codebases so it doesn't cost precision somewhere else.

How we measure recall

Recall is easy to inflate, because every shortcut in measuring it makes it go up. These are the rules we hold ourselves to:

Truth first
Recall is measured against an answer key written by reading the code, never one built from the scanner's own output. A key made from what the tool reported can only say the tool found everything.
Where it counts
A defect counts as found only if it appears on the list the customer actually reads. A finding filed in a drawer or a review queue is recorded as buried, not found.
Unread is missed
Defects in files no engine examined count as misses, not as "out of scope".
Keys only grow
When we find a real defect the key never listed, we add it. That makes the test harder: the new defect has to be found on every later scan too.
Latest, not best
AI findings vary from run to run, so every score names its scan and commit, and we report the latest scan, not the best one.

Our recall today

CodebaseWhat it isRecall
Customer monorepo A production system: web and desktop apps, backend services, cloud infrastructure and CI. The key was built by reading every finding against the source, then checked with a blind review of the attack surface. 97.8%44 of 45
Scheduling platform A large open-source TypeScript codebase, about 5,000 files. The key comes from a full review of every file, extended with defects found in later audits. 94.3%33 of 35
OWASP Juice Shop An application that is insecure on purpose, with an unusually high share of business-design flaws. 80.0%64 of 80

Latest scans as of 23 September 2026, counted on the findings list a customer reads.

What the misses are

The misses say more about a scanner than its hits do, so here are ours. On Juice Shop, most of the remaining misses are business-design flaws the code never states. A quantity that can go negative. Discount codes that are encoded but not signed. A one-time secret stored in plain text. An admin list that any signed-in user can open. Recognising these means knowing what the business intended, and that is where we are investing next. On the other two codebases, the few misses are mostly run-to-run variation: a finding one scan reports and the next does not. We track those and move them to deterministic checks where we can.

What to ask any vendor about recall

  1. Who wrote the answer key, and was it built by reading code or from the tool's own output?
  2. Does a finding count if it's hidden, in a drawer, a review queue or a low-severity bucket?
  3. Are unscanned files counted as misses, or quietly left out of the denominator?
  4. Is the number from one scan or the best of several, and which commit was scanned?
  5. What did it miss? A vendor who can list its misses has measured its recall. One who can't has only measured its hits.

Vybscan scans dependencies and code on every pull request and on demand. The figures above come from our internal benchmark harness. The customer is described without identifying details.

See what Vybscan finds on your repos

SCA, secrets, and SAST on every GitHub pull request, with a built-in dashboard.

Try Vybscan โ†’
โ† Back to Blog