The reliable way to reduce false positives is to stop accepting unvalidated findings. Most false positives are not defects in a tool; they are the tool doing its job, which is to report that something MIGHT be exploitable and leave the verification to you. Tuning and suppression manage that symptom. Validation removes it. See our validation-first penetration testing for what that validation looks like in practice.
This matters more than it sounds, because the cost of false positives is not really wasted time. It is lost trust. A team that has dismissed a hundred findings develops a reflex, and the reflex does not distinguish the hundred and first.
Why they happen
Four causes account for most of the volume, and only one of them is a tool defect.
Signature matching without context. A scanner sees a library version listed in a known-vulnerable range and reports it. Whether your application ever calls the affected function is a question it did not ask.
Reachability is unknown. A pattern in the code may be genuinely dangerous and sit behind an authorisation check, a feature flag, or a code path nothing invokes. Static analysis sees the pattern, not the path.
Configuration inferred, not tested. A missing header, a permissive setting, an open port reported without establishing what it actually allows.
Genuinely wrong detection. The smallest category, and the one everyone blames.
What most teams do about it
The standard response is tuning: adjust thresholds, write suppression rules, mark findings as accepted risk. It works, in the narrow sense that the number in the dashboard goes down.
It also quietly creates a second problem. A suppression list is a set of decisions made once, by someone who may have left, about an application that has since changed. The rule that correctly ignored a finding in March may be hiding a real one by November, and nothing prompts anyone to look.
The worse version is threshold tuning to quieten the noise. Raise the bar until the queue is manageable and you have not improved precision - you have traded false positives for false negatives, which are the expensive kind because nobody ever sees them.
The uncomfortable arithmetic: every knob that reduces false positives without adding evidence is also reducing true positives. You cannot tune your way to accuracy, only to a quieter queue.
What actually reduces them
- Require validation. A finding that was exploited, with reproduction steps, cannot be a false positive. This is the only change that removes the category rather than managing it.
- Establish reachability before triaging severity. Whether the vulnerable path is reachable from an untrusted input matters more than the CVSS number attached to it.
- Separate the queues. Confirmed findings and unconfirmed signals should not sit in the same list. Mixing them means the confirmed ones inherit the credibility of the noise around them.
- Review suppressions on a schedule. If a rule cannot be justified again today, it should not still be running.
- Track false negatives too. Every time a real finding turns up that your tooling should have caught, ask which tuning decision filtered it. That number is the one nobody measures.
The distinction worth internalising
There are two different things a tool can hand you, and they are frequently presented identically.
| Unvalidated signal | Validated finding | |
|---|---|---|
| Claim | This may be exploitable | This was exploited |
| Evidence | A pattern or version match | Reproduction steps |
| Who does the triage | Your engineers | Already done |
| Can it be a false positive | Yes, by construction | No |
Neither is useless. A signal is a reasonable input to an investigation. The mistake is treating a queue of signals as a security posture, and then blaming the tool for the volume it was built to produce.
This is the specific problem our validation-first approach is designed around: attempt the exploit, and report only what actually worked.