Vulnerability Management

Evidence and Re-testing: Proving a Finding Is Actually Fixed

By PMAP Security Team 18 min read

A finding marked “fixed” is a claim. Until someone verifies it, that claim is the same weight as a Slack message that says “should be done.” Vulnerability programs that close findings on assertion alone accumulate a quiet liability. The issue is recorded as remediated, the metric improves, and the underlying weakness is still exploitable. Closure without proof is how a clean dashboard ends up disagreeing with a penetration test report three months later.

This article is about the layer that closes that gap. It covers how to attach structured proof to a finding, how to view scanner-supplied evidence without leaving the platform, and how to run the two re-test cycles that move a finding to closed for a reason rather than on a hunch. The focus is the evidence and re-testing layer specifically. Status transitions, severity, and assignment belong to the triage layer, and this piece links to them where the two meet. If you want the broader picture, this is where re-test fits in the full vulnerability management lifecycle.

Why Proof Belongs in the Finding, Not in Email

Most teams already do some form of verification. The problem is where the proof lives. Reproduction steps end up in a ticket comment. A screenshot of a passing re-scan sits in a chat thread. The pentester who confirmed the fix mentions it in a stand-up and nobody records who, when, or against what. Each of these is real verification work, and each one is invisible the moment you need to defend the closure.

There are three costs to scattered proof. The first is auditability. When an assessor, a customer security review, or an internal audit asks “show me that this was actually remediated,” the answer cannot be a search across mailboxes. The proof has to be reconstructable from the finding record itself, with timestamps and named individuals. The second cost is context-switching. Analysts who have to leave the platform to read a code snippet in the scanner UI, then come back to record an outcome, lose time on every single finding. At backlog scale that overhead is enormous. The third cost is traceability. If a finding reopens later, you want to know which re-test passed it, who ran that re-test, and what tools they used. Free-text notes rarely preserve that chain.

PMAP’s answer is to make the finding the system of record for its own verification. Structured evidence fields live on the finding. Vendor artefacts render inside the finding. Re-test records attach to the finding with a timestamp and an author. When someone asks whether the issue was fixed and how anyone knows, the finding answers the question by itself. That single property, proof embedded in the record rather than around it, is what makes everything below worth building.

Structured Evidence Beats Free Text

The first half of the evidence layer is what the human records. PMAP captures reproduction details as discrete fields rather than one large text box. A finding carries steps_to_reproduce, used_tools, used_accounts, access_point, access_profile, and exploit_status. These are first-class fields on the finding model. They are stored with the record and returned with it, so they travel everywhere the finding travels, including into reports and exports.

Why does the shape of these fields matter? A free-text evidence box is easy to write and hard to trust. One analyst writes a paragraph. Another writes a bullet list. A third writes “see scanner.” Three months later nobody can tell from the field alone what tools were used or whether the issue was actually exploited or only theoretically present. Discrete fields force a consistent answer to consistent questions. What is the access point. What was the exploit status. Which accounts were used to reproduce it. The data becomes comparable across the team and across findings.

The structured shape also serves the remediation owner, who is often not the person who found the issue. A developer asked to fix a vulnerability needs to replicate it first. Vague evidence means a back-and-forth that burns days. Precise reproduction steps with the exact access point and the exact accounts used let the owner reproduce the issue on the first attempt and confirm the fix on their own. Good evidence is not bureaucracy. It is the shortest path from “this is broken” to “this is fixed.”

Discrete Searchable Fields for Consistent Quality

There is a practitioner reason these fields are not one blob. When used_tools and used_accounts are arrays and access_point and exploit_status are their own controls, evidence quality stops depending on how diligent the individual analyst felt that day. A pentester authoring a manual finding fills the same controls a scanner-sourced finding would expose, so a hand-authored finding and an imported one carry comparable evidence. The fields being discrete is what makes evidence a property of the program rather than a habit of one careful analyst.

These fields also tolerate the realistic case of partial data. The used_tools and used_accounts arrays can be empty, and the interface is built to handle a zero-item array cleanly rather than render an empty placeholder row. Not every finding needs every field populated. A finding with no tools recorded is still a valid finding. The model captures what is known without demanding what is not, which keeps analysts honest instead of pushing them to invent detail to satisfy a form.

Vendor Artefacts Rendered In-Platform

The second half of the evidence layer is what the scanner already knows. Modern code and dependency scanners produce rich artefacts. A SAST tool that flags an injection vulnerability can show you the exact vulnerable line and the data-flow path that reaches it. An SCA tool that flags a vulnerable package can show you the dependency chain that pulled it in. This is valuable evidence that analysts historically had to go and read in the scanner’s own console.

PMAP brings three of these artefacts into the finding’s Evidence tab. SAST findings show a code snippet for the vulnerable location and a taint flow that traces the path from source to sink. SCA findings show a dependency graph, the transitive dependency tree for the vulnerable package. Each renders inline. The analyst opens the finding, opens the Evidence tab, and reads the scanner’s own evidence without logging into the scanner.

The practical payoff is triage speed and triage accuracy at the same time. A taint flow tells an analyst in seconds whether attacker-controlled input genuinely reaches a dangerous sink, which is the difference between a real injection and a false positive that the scanner flagged on a tainted-looking but actually safe path. A dependency graph tells you whether the vulnerable package is a direct dependency you control or a transitive one buried three levels down, which changes the remediation approach entirely. These artefacts are not decoration. They are the inputs to the decision the analyst is about to make. Reading them in context is a measurable reduction in tool-switching, and it raises the quality of the decision because the evidence is right there next to the verdict.

The Integration Is the Source of Truth

There is an architectural choice underneath the convenience, and it matters. The vendor artefacts are not copied onto the finding row. They are fetched on demand from the linked scanner integration. A single GET /evidence call returns the available bundle, and individual endpoints back the code snippet, taint flow, and dependency graph panels. The integration remains the authoritative source.

This design has two consequences worth understanding. The first is freshness. Because the artefact is pulled live rather than stored at import time, what you see reflects the scanner’s current view, not a snapshot frozen at ingest. The second is graceful degradation. A finding with no linked integration, such as a manually authored pentest finding, simply returns empty artefacts. No error, no broken panel. And if the integration is unreachable or its token has expired, the evidence panel shows an error state while the finding itself is completely unaffected. The proof layer can have a bad day without the finding losing its identity or its other evidence. Live fetch trades a little latency for a lot of correctness, which is the right trade for evidence you may have to stand behind.

The Analyst Re-test Cycle

Capturing evidence proves the issue existed. Re-testing proves it stopped existing. The analyst re-test cycle is the human-driven path to verified closure, and it is deliberately a formal record rather than a status flip.

When an analyst runs a re-test, PMAP produces a FindingRetest record. That record carries a timestamp and the identity of the person who performed it. It is not a comment and not an implicit side effect of changing status. It is a first-class artefact that says “this individual verified this finding at this moment.” That is exactly what an auditor, a manager, or a future version of your own team needs when they ask who signed off on a closure.

The re-test ties directly into the status state machine. The full machine, with all its allowed transitions and terminal states, is governed by the triage layer, but the part that concerns re-testing is worth stating plainly. The retest transition is permitted only from in_progress. You cannot re-test a finding that nobody has started working. From retest, a pass moves the finding to closed and a fail moves it to reopened. So a positive re-test is the legitimate route to closure, and a negative one routes the work straight back into the queue rather than letting a failed verification quietly disappear. Closure earns its terminal state through a recorded pass, not through someone deciding the ticket looked done.

This is where the boundary with triage is cleanest. If you want the full set of statuses and the reasoning behind the state machine, that lives in the finding triage workflow. For re-test purposes, the only transitions that matter are the three above, and they exist specifically so that closure and reopening are both consequences of evidence rather than opinion.

Async Vendor Re-testing for DAST

Not every re-test is best run by a human. For dynamic application security testing, the scanner that found the issue is often the most reliable tool to confirm it is gone, because it tests the running application exactly as it did the first time. PMAP supports this with an asynchronous vendor re-test track.

An analyst starts a vendor re-test with a single action, which calls POST /vendor-retest. This is valid only for findings whose source integration supports the vendor re-test capability, which today means DAST scanners exposing that adapter, including Acunetix, Invicti, and Burp. The call does not block. It starts a job on the scanner and returns immediately with a job identifier. The interface then polls GET /vendor-retests/{retestId} for status, and the Retests tab reflects the vendor’s job state as it progresses from pending to running to a final result.

The asynchronous design is a deliberate fit for how scanners actually work. A real DAST re-test is not instant. It can take minutes. A synchronous call that waited for completion would block the analyst and tie up a request for the duration of an external job. By starting the job and polling, PMAP lets the analyst move on and return when the result is in. This is the right shape for any verification that depends on an external system doing real work, and it is why the platform polls rather than pretends the result is immediate.

If you call vendor re-test on a finding whose source does not support it, the API tells you the capability is not supported for that finding’s source integration rather than failing silently. The mechanics of how each DAST connector exposes this capability belong to the integration layer, and you can go deeper on that in the dedicated DAST integration guide. For the purposes of verification, the value is simple. The tool that found the vulnerability is the tool that confirms its removal, and the analyst orchestrates that from inside the finding.

When auto_close_on_resolve Should Stay Off

Integrations expose a configuration flag called auto_close_on_resolve, and it governs what happens when an external system reports an issue resolved. When the flag is true, a positive vendor re-test result can close the finding directly. When it is false, which is the default, the same positive result only transitions the finding toward re-test for analyst sign-off. The default exists for a reason, and understanding that reason is the difference between a program that looks automated and one that is actually governed.

The temptation is to turn it on. Auto-close looks efficient. The scanner says fixed, the finding closes, the backlog shrinks without anyone touching it. The problem is that a scanner reporting “no longer detected” is not the same statement as “remediated.” A finding can disappear from a scan because the asset was offline, because the scan scope changed, because a control temporarily masked the issue, or because the vendor’s detection logic shifted. None of those are fixes. An auto-close on every “resolved” signal converts every one of those non-fixes into a closed finding that nobody verified.

Leaving the default in place keeps a human in the loop at the moment that matters most. The analyst sees the vendor result, considers whether it is a genuine remediation, and produces the signed-off re-test record that makes closure defensible. For a high-volume program with low-severity noise you may decide the automation is worth it. For anything you would have to justify to an auditor or a customer, the conservative default is the right one. The platform ships cautious on purpose, and that caution is itself a feature.

Re-open Accounting and Evidence Preservation

Findings reopen. A fix regresses, a deploy reverts, a workaround expires, or a later scan rediscovers the issue. A verification layer is only trustworthy if it handles reopening correctly, and PMAP handles it in two specific ways that protect the integrity of the record.

First, reopening is counted, not hidden. When a finding reopens, the state machine increments its reopen_count. This is wave-visibility accounting, and it turns a recurring problem into a visible number. A finding that has reopened four times is telling you something a single open finding is not. It is telling you the fix keeps failing, or the issue keeps being reintroduced, or the verification was not thorough enough. Counting reopens surfaces the findings that deserve a harder look instead of letting them cycle quietly through open and closed.

Second, and this is the part that protects auditability, evidence is not reset on reopen. The reproduction steps, the tools, the accounts, the access point, all of the structured evidence captured the first time survive the reopen. The original proof of the original issue is preserved. This matters because the history of a recurring finding is itself evidence. You want to compare the new occurrence against the old one, and you cannot do that if reopening wiped the slate. PMAP keeps the evidence so that a finding’s full verification history stays intact across every cycle it goes through.

What Re-test Metrics Tell You

The evidence and re-test layer produces data, and that data answers questions a vulnerability program should be asking about itself. PMAP surfaces several re-test metrics, and each one maps to a real operational question.

Mean time to re-test measures the gap between a finding entering retest and an outcome being recorded. A growing number here means verification is becoming a bottleneck. Findings are sitting in re-test waiting for someone to confirm or deny them, which delays both legitimate closures and the reopening of failed fixes. Re-test pass rate, the ratio of closed to reopened outcomes, tells you something about remediation quality upstream. A low pass rate means fixes are failing verification often, which points at the remediation process rather than the verification process. Vendor re-test job completion time tracks how long the async DAST track takes to return.

Two coverage metrics are worth watching together. The percentage of closed findings with at least one re-test record tells you how much of your closure is actually verified versus asserted. If that number is low, your clean dashboard is built partly on unverified closures. The percentage of findings with structured evidence captured tells you how much of your backlog carries the proof you would need if challenged. These two numbers are the honest measure of whether your program closes on evidence or on optimism. A team that watches them tends to close fewer findings on faith over time, which is the entire point.

How PMAP Makes Verification Auditable

Pulling the threads together, the value of this layer is not any single feature. It is that verification becomes a property of the record rather than an activity that happens around it. Structured evidence lives on the finding. Vendor artefacts render in the finding from the authoritative integration. Re-test records attach to the finding with a timestamp and a named author. Reopens are counted and the original evidence is preserved across them. The default keeps a human in the loop at closure.

The result is a finding that can defend its own closure. When an auditor asks how you know an issue was remediated, the finding shows the structured reproduction evidence, the scanner artefact that informed the analysis, and the re-test record that names who verified it and when. When a customer security review asks the same question, the answer is the same record. When your own team revisits a finding that reopened, the full history is intact. Enterprise vulnerability programs need proof before closure, and PMAP makes that proof a permanent part of the finding instead of a fragile trail across email, chat, and scanner consoles.

To see exactly how an analyst attaches proof and runs a verification end to end, walk through re-testing a finding with evidence in the step-by-step guide. To understand the related testing methodology, the OWASP Web Security Testing Guide and NIST SP 800-115 on technical security testing and assessment are useful external references, and the MITRE CWE list helps classify findings by root cause.

Frequently Asked Questions

What is the difference between evidence and a re-test in PMAP?

Evidence is the captured proof that a finding exists and how to reproduce it, including structured fields like steps to reproduce, used tools, used accounts, access point, and exploit status, plus vendor artefacts such as a SAST code snippet, a taint flow, or an SCA dependency graph. A re-test is the act of verifying whether the finding has been remediated, recorded as a formal re-test record with a timestamp and an author. Evidence proves the problem. The re-test proves the fix.

Can I close a finding without a re-test record?

The state machine routes closure through the retest status, and a re-test pass is what transitions a finding to closed. The platform also tracks the percentage of closed findings that carry at least one re-test record, so you can measure how much of your closure is verified rather than asserted. Watching that metric is how a team keeps itself honest about closing on proof rather than on assumption.

Which scanners support automated vendor re-testing?

Vendor re-testing is available for findings whose source integration exposes the vendor re-test capability, which today applies to DAST scanners including Acunetix, Invicti, and Burp. Starting a vendor re-test on a finding whose source does not support it returns a clear error stating the capability is not supported for that source integration, rather than failing silently.

Where do the SAST code snippet and SCA dependency graph come from?

They are fetched live from the linked scanner integration when you open the Evidence tab, not stored on the finding row. The integration is the source of truth. A finding with no linked integration returns empty artefacts gracefully, and if the integration is unreachable or its token has expired, the evidence panel shows an error state while the finding itself is unaffected.

Should I enable auto_close_on_resolve?

The flag defaults to false, which means a positive vendor re-test routes the finding to re-test for analyst sign-off instead of closing it directly. The default keeps a human in the loop because a scanner no longer detecting an issue is not the same as the issue being remediated. Enabling auto-close suits high-volume, low-severity noise. For anything you may need to defend to an auditor or a customer, leaving the default in place is the safer choice.

What happens to evidence when a finding reopens?

Evidence is preserved. When a finding reopens, the state machine increments its reopen_count so the recurrence is visible, but the structured evidence fields are not reset. The original reproduction steps, tools, accounts, and access details survive every reopen, which keeps the finding’s full verification history intact for comparison and audit.

How does re-testing fit into the wider vulnerability process?

Re-testing is the verification step that turns a remediation claim into a closed finding. It sits after triage and assignment and before final closure, consuming the evidence captured earlier and producing the proof that justifies a terminal state. For the complete sequence of stages around it, see how it connects inside the full vulnerability management lifecycle and how it hands off from the finding triage workflow.

author avatar
PMAP Security Team

Newsletter

Get the next writeup in your inbox

One short email when a new case writeup or detection deep dive ships. No marketing drip, no third-party tracking.