Why your penetration test findings never reach production.
A penetration test is a procurement event that produces a document. Everything that makes it useful happens after the report is delivered — and almost none of it is engineered.
9 min read
Every security team we talk to has the same artefact: a 120-page PDF from two years ago, stored in a drive nobody can search. The findings in it were real. Some were fixed. Many were not, and the team has no way of knowing which is which, because the only machine-readable version of that assessment was an email attachment.
This is not a testing problem. The testers did their job. It is a lifecycle problem: the test produces a document, and documents do not carry state.
The gap is state, not testing
A finding has to move through a sequence of states — open, accepted, in remediation, fixed, verified, closed. It also has to carry an owner, a deadline, evidence and a history. A PDF can express none of that. A Jira ticket can express all of it, which is why well-run programmes smuggle findings into their tracker within a day.
The programmes that do this well have a boring property: nobody talks about the penetration test as a special event. It is a phase inside a continuous process, with the same ticket shape as everything else the team already ships.
Where findings actually die
- 01In the debrief — the tester explains it verbally, the team writes notes, and the notes do not match the report.
- 02In the spreadsheet — somebody retypes the criticals into a tracker, and the CVSS vector is dropped along the way.
- 03In triage — severity becomes an argument, and the low-value findings crowd out the two that mattered.
- 04In the queue — a finding with no owner, no SLA and no link to the affected service is indistinguishable from a piece of backlog theatre.
- 05At retest — nobody verifies the fix, so the finding never closes and the next report re-raises it as new.
What a finding has to carry to survive
We have converged on a fairly short list. Anything not on it is a field we let engineers skip, because a mandatory field nobody fills in is worse than no field.
| Field | Why it is non-negotiable |
|---|---|
| Affected asset | Ownership is derived from the asset, not assigned by hand |
| CVSS vector | Removes the severity argument; severity is derived, not declared |
| Reproduction steps | The engineer should be able to reproduce it without the tester |
| Evidence | Raw request/response plus a PoC — this is what survives a dispute |
| Remediation guidance | A patch, a config change, or a design note |
Automation earns its keep here
The scanner's job is not to be the source of truth. It is to be the thing that never forgets to re-check. A finding that a human verified once in August should be re-verified every week, for free, without anyone scheduling it. That is the part a scanner can genuinely do better than a person, and it is the part most programmes throw away by exporting to CSV on day one.
“We stopped arguing about whether findings were real. Evidence ships with every one of them, so the conversation is about the fix — not the proof.”
R. Okafor, Head of Security, Northwind Payments
The shift is small in code and large in culture: the test is not the deliverable. The closed ticket is the deliverable. Everything else — the scan, the retest, the report — is machinery in service of closing things.
keep reading
VAPT programme · 9 min