A scanner points at your target and lights up: forty findings, half of them flagged critical. Here's the part nobody warns you about — most of them aren't real. And the engineer who triages your report already knows it.
So the skill that actually decides whether you get paid isn't running the scanner. It's telling the four real findings from the thirty-six false alarms before you hit submit. That's the whole job. This post is about how to do it.
(The "forty findings" is an illustration, not a statistic — but if you've hunted for a while, the ratio won't surprise you.)
What a scanner actually does
A scanner matches patterns. It sends a payload, sees your input reflected back in the response, and writes down possible cross-site scripting. What it never did was check whether that script actually runs. It saw the door. It never walked through it.
That's detection, and detection only answers one question: is something here? Which is a guess. Security teams get hundreds of those a week from their own tooling. They don't pay for guesses. They pay for the next thing — proof.
What proof actually is
Proof is a reproducible, harmless demonstration that the bug does the thing you claim — not that it might, that it does.
- For a reflected value, proof isn't the reflection. It's the
alert()actually firing from your payload. - For broken access control, proof isn't a weird ID in the URL. It's you holding data from an account that isn't yours.
Detection says "this parameter looks dangerous." Proof says "here is the exact request, and here is the damage it did, on demand." Everything that makes a report valid lives in that gap.
The three-question test
Before any finding earns a report, make it survive three questions.
1. Can you trigger it on demand?
Reproduce it twice, from a clean session, cookies cleared. A bug you can only hit once isn't a finding — it's a coincidence, and it will come back cannot reproduce.
2. Can you show impact, not just presence?
This is the one that gets reports closed. You found XSS — so what? "It's there" is not an answer. "Here's a payload that lifts a logged-in user's session cookie" is. Paint the worst realistic case and show one step of it.
3. Is it in scope, and is your proof safe to run?
Check the rules of engagement before you demonstrate anything. Proof means a benign payload — one that proves control without dropping a table or reading real customer data. A proof that causes damage isn't a bounty. It's an incident.
Reproduce, impact, scope. A finding that answers all three is real. One that can't answer even one isn't ready — and most of your scanner's forty can't answer any.
Write the report as proof, not as a label
The report that gets paid is an equation, not a noun. Don't send "I found SQL injection." Send:
- the request you sent,
- the exact payload,
- the response that proves it (the delay, the row, the leaked error),
- and one line of impact: what an attacker does with this.
Same bug, two reports. One says XSS in search. The other says here is the request, here is the alert firing, here is how it steals a session. The first gets closed. The second gets a bounty. The difference was never the bug — it was the proof.
A worked example: proof by timing
Time-based SQL injection is the cleanest way to feel the detection-vs-proof line, because the proof is just a stopwatch.
You add a condition that says: if this input is really reaching the database, wait five seconds. Then you compare it against a clean baseline.
# Baseline — normal input
curl -s -o /dev/null -w "%{time_total}s\n" \
"https://target.example/item?id=42"
# -> 0.12s
# Payload — ask the database to sleep IF it's injectable
curl -s -o /dev/null -w "%{time_total}s\n" \
"https://target.example/item?id=42%20AND%20SLEEP(5)--"
# -> 5.13s
The clean request returns instantly. The payload takes five seconds longer — on demand, repeatable. That gap is the proof. You never read a single real record; you just showed the database obeyed you.
baseline : 200 0.12s
payload : 200 5.13s
Δ : +5.01s <- this is the finding
Attach that delta, the two exact requests, and one line of impact, and you have a report that triages instead of bounces.
Automating the proof step
The three-question test is mechanical, which means it's automatable. That's exactly the problem my team built Xalgorix around: for every finding, it replays the request with a proof payload, watches what actually comes back, and then a separate verifier re-tests the finding from scratch before it ever reaches the report — non-destructive by design. It's open source (Apache-2.0), so you can self-host and read every line, or run it on Xalgorix Cloud.
Disclosure: I work on Xalgorix. The three-question test above stands on its own whether you reach for any tool or not.
The habit
Next time a scanner hands you forty findings, don't report the list. Report the one you can prove. That's the hunter the programs remember.
Top comments (0)