ScanBastion Join Early Access

Learn

Why automated vulnerability scanners report false positives, and what to do about them

Every automated vulnerability scanner reports things that are not there. That is not a defect of one product; it follows from what scanners can observe from outside. Knowing why false positives happen is the fastest way to spot them, and a short triage routine keeps them out of the reports you hand to clients.

Where false positives come from

1. Version detection stands in for vulnerability detection

The most frequent source. A scanner sees jQuery v1.12.4 in a file header, or WordPress 6.2 in a meta tag, or nginx/1.18.0 in a response header, looks up the advisories for that version, and reports them. Three things can make this wrong: the vulnerable function is never called by the site; the distribution backported the fix without changing the version number (Debian and Red Hat do this routinely); or the version string is simply stale, left in a comment after an upgrade. The finding is "this version has advisories", not "this site is vulnerable", and a good scanner says so with a medium confidence rating.

2. Pattern matches on ambiguous content

Scanners recognise error messages, stack traces, private IP addresses and secrets by pattern. A themed 404 page that includes the words "SQL syntax" in a joke, a documentation page that shows an example AWS key, or a blog post about internal networks that mentions 192.168.1.1 will all match. The scanner cannot read for meaning.

3. Reflection is not injection

Passive scanners notice when a value from the URL appears in the page. That is the precondition for reflected cross-site scripting, so it is worth flagging, but most sites encode output correctly and the reflection is harmless. Without sending a payload, which a passive scan by design does not, the scanner cannot tell the two apart.

4. Infrastructure answering for the application

CDNs, WAFs and load balancers sit between the scanner and the site. They may return a friendly 200 page for any path, which makes every "exposed file" template look like a hit; add or strip headers; or block the scanner's requests and return responses the application never produced. A directory-listing finding that turns out to be a CDN's generic page is a classic.

5. Context the scanner cannot see

An "admin panel exposed" on a URL that requires VPN access at the network layer; a "missing HSTS" on a hostname that is only ever reached by redirect from one that sets it; a cookie without Secure that stores a language preference. The scanner's rule is correct in general and wrong here.

Telling real from mistaken in under ten minutes

For each finding, look at the evidence the scanner attached: the request it made and the relevant part of the response. Then ask, in order:

  1. Can I reproduce it? Make the same request yourself with a browser or curl. If the response differs, suspect a WAF or caching layer, and note that the scanner's view may not be a visitor's view.
  2. Is the match about the application or about the infrastructure? Check whether the response came from the origin or from an edge page.
  3. For version findings: is the vulnerable code reachable? Search the site's JavaScript for the affected function; check whether the plugin is actually active; ask the developer whether the dependency is pinned and patched.
  4. For reflection findings: is the output encoded? Look at the HTML source around the reflected value. &lt; instead of < means it is.
  5. Does the context change the severity rather than the truth? A finding can be true and unimportant. Keep it, lower the severity, and write down why.

Record the outcome against the finding: confirmed, false positive, or true-but-accepted, with one sentence. The next scan should carry that decision forward so you do not do the work twice, and so a client's report shows a stable picture rather than a new list every month.

What a false-positive rate tells you about a scanner

Zero false positives is not the goal, and a scanner that claims it is either very narrow or marking everything as informational. The signs of a scanner that handles uncertainty well are: a separate confidence field rather than one severity number; evidence attached to each finding; a review state you control; and clear statements of what was not checked. The guide Severity, confidence, verification explains why those three fields matter and how to triage with them.

False negatives are the quieter problem

Every hour spent on false positives is visible. Issues the scanner missed are not. External, unauthenticated scanning cannot see behind log-ins, cannot test business logic, and cannot find novel flaws in custom code. A clean report is a statement about the checks that ran, not about the site. Say so in the report, every time, and point clients toward manual testing for anything where the stakes justify it. The guide What a website vulnerability scan does and doesn't cover maps the boundary in detail.

A triage routine for agencies

  • Run the scan, then sort by confidence first, severity second. High/high findings get verified immediately; they are usually few.
  • Batch the high-severity, medium-confidence findings into a single review session rather than reacting to each.
  • Mark decisions in the tool so they persist. A false positive dismissed by email is a false positive you will dismiss again next month.
  • In the client summary, report confirmed and needs-review counts separately. Never present an unverified count as "vulnerabilities".
  • After fixes, rescan and attach the before-and-after to the invoice. Verified remediation is the deliverable clients remember.