After the Report is Delivered: Remediation and Confirmation Testing

Aug 17 2026

You’ve received a penetration test or security review report. The summaries are read, the report read-out meeting has happened, and now the hard part begins! This article discusses what to do after you receive your report. We’ll talk about the process from reproducing findings and implementing fixes, through to engaging confirmation testing efficiently. Getting familiar with this process can have some sweet additional benefits, like implicit security upskilling!

This is the fourth article in our Purpose and Execution of Penetration Testing series, following on from The Purpose of Penetration Testing, Timeboxed Penetration Testing and What Makes a Quality Penetration Test.

After receiving a penetration testing report, you’re presented with a list of findings. In the case of Pulse Security, these are rated by technical severity and tagged as either bugs, security hardening issues, or architectural weaknesses. The next steps are to understand these findings, figure out who can address them or who to escalate them to, and then triage and remediate the issues. The remediation path isn’t always straightforward. Sometimes issues resist easy fixes, and we need to reach for other tools like compensating controls or a longer-term entry on the (often maligned) risk register.

Let’s discuss what the steps for remediation and post-pentest-report activities can look like. Just as a disclaimer, at this part of the process I usually become more of an advisor and support person rather than a hands-on direct-fixer-of-the-things, so these next sections represent my ideal world. Reality often has more complexities. Any process needs to have room for flexibility.

Assigning Ownership

Whose problem is it?!

Step one is figuring out who has the ability to make the changes and implement the remediations for each specific finding. Sending development findings to the sysadmins probably isn’t going to be super useful (or win you any friends); similarly, bugging the devs about server hardening specifics probably isn’t going to play out great either.

My only advice for this section is to talk openly with all your teams and relevant vendors. Your security consultants who have written the report can have some insights on who would be best placed to remediate a given finding, too.

Once you’ve found the folks that’ll be responsible for triaging and remediating the findings, these next sections are written for them too!

Triage

As we’ve discussed in the previous articles, our penetration test and security review reports contain findings categorised as bugs, hardening recommendations, and architectural issues (see The Purpose of Penetration Testing for the breakdown). Each category requires a different approach to remediation.

Triaging a finding can look something like this:

The first and most critical step is understanding the finding, which is best done by reproducing it yourself. This means replicating the steps detailed in each finding and ensuring you can see the same behaviour the security consultant highlighted.

This ensures both the person who wrote the report and the person triaging have a shared technical understanding to work from. If the finding can’t be reproduced, that’s something to go back to your pentester about and ask for more information.

As an aside, this is why I don’t like including screenshots of commercial security tools like BurpSuite as evidence in reports. What if the person remediating the finding doesn’t have or understand BurpSuite? They’ll certainly have a browser though, and curl is installed by default on every major operating system now.

Reproduce the Finding

For a well-written finding (provided there aren’t complex preconditions to trigger the issue) reproduction should be a case of reading through the technical details of each finding and attempting to reproduce the conditions described by the tester. If you cannot reproduce the condition described by the tester, it’s challenging to proceed with remediation. Reach out to the tester and ask questions. A good finding should have enough detail for reproduction, and if it doesn’t, that’s a discussion worth having. The pentest firm’s reporting standards go up, and the client gets clearer finding evidence. Everyone wins!

Reproducing findings yourself is also wonderfully valuable internal training. The process of reproducing the security consultant’s steps to see the finding first-hand gives the person triaging the issue hands-on time with the tools and techniques security consultants use themselves to find the issues in the first place, in a more digestible byte-sized chunk.

For example, issuing requests manually with tampered data to trigger an input-based vulnerability, or altering parameters in a URL to exploit a weak authorisation check. It helps your team understand the vulnerability, how it was discovered, and what an attacker would see. This knowledge is useful when explaining the issue to stakeholders (how to communicate complex technical topics in ways appropriate for non-technical colleagues is a whole thesis in and of itself!), or when hunting for similar issues elsewhere in the system.

I need to stress how critical the reproduction step is. Without it, the fixes can end up being applied blindly and can be ineffective, then we have a loop-condition between the techs and the consultants. That’s inefficient (read: expensive) and can be frustrating for all involved.

Bugs

Bugs are erroneous logic or configuration, think SQL injection or missing access controls. The remediation path sounds straightforward on paper: replicate the bug, fix the logic, demonstrate the resolved case, and show your work.

“Just fix it” is where the complexity hides. The word “just” is load bearing in computer engineering. Shout out to XKCD for explaining the problem much quicker than I possibly could.

Before you start changing code, it’s beneficial to understand the full scope of the vulnerability. Are we dealing with an edge case in an otherwise secure system, or is this a repeating pattern? The Manage My Health breach write-up by CCX (PDF - 4.3.1 Historical security testing reports) had some interesting notes that penetration testing regularly found the same type of bug, just different instances of it, and the breach exploited another instance of that same vulnerability class. Edge cases versus repeating patterns, it’s important!

Where else in the code base does the bug pattern appear? Is this a single endpoint issue, or a systemic problem in how the application handles input? A fix which patches one endpoint but leaves five others vulnerable isn’t great. You can use tools like semgrep to look for similar patterns, or any of the various other coding automation tools that are kicking around now. We’ll discuss edge cases versus repeating patterns in a little bit.

If we’re genuinely looking at a single outlier, then patch that, and maybe we can consider long-term how the bug got there, and if any other belts and braces could stop other instances from popping up in the future. Remember it’s possible to make all the right moves and still end up with some edge case somewhere that exposes a vulnerability. That’s life, and incidentally one of the reasons you’d be doing penetration testing in the first place.

If it’s a repeating pattern, I’d suggest looking at turning the output of the finding into some form of SAST/DAST or automated check, and making a note of any other instances for the evidence and confirmation phase (more on this soon!)

Sometimes the bug is in someone else’s code. A vendor’s proprietary component, a third-party library, or a legacy system that’s no longer supported. You probably can’t write a patch for someone else’s software, but that doesn’t mean you’re stuck. Look at containment: can you restrict access to the vulnerable component? Can you add monitoring and alerting to detect the condition? Can you isolate the component behind additional authentication controls? This is more of a work-around and compensating control, but still valuable and an improvement to the security posture of the target.

Also, in light of the current supply-chain debacles unfolding in the software library space… If you’re importing a whole library just to use one small feature, then consider re-implementing that feature yourself and trimming the library dependency. I know cyber-security weenies like myself have said “don’t roll your own!” for a long time, but in our defence, that was about cryptographic primitives and not left-padding a string. Maybe a test uncovering a bug in that library is a good excuse to finally get rid of it?

When you do implement a fix, test it thoroughly. The original attack path should be closed, but have you checked for similar issues elsewhere? Have you tested edge cases? You can even try modifying and mutating the test-cases a bit to make sure fixes work effectively.

The key here is showing the resolved case. Show the specific code or configuration change, explain how it resolves the issue, and demonstrate that the original attack path no longer works. This is the evidence that feeds into efficient confirmation testing when you pass it back to the tester.

I’ve done too many confirmation testing engagements where the client says “we fixed it” and then I need to spend hours (read: dollars) figuring out what’s actually changed. If you include the code changes or configuration snippet in your remediation notes, along with some testing evidence, it saves everyone time. So much time, in fact, that it’s what prompted writing this article!

Hardening

Hardening findings discuss missing security controls or hardening mechanisms that reduce the likelihood of exploitation or future vulnerabilities. This includes both fundamental security controls, such as transport-layer encryption, as well as defence-in-depth controls such as rate limiting or security alerting. A test could find no bugs in a target, but could highlight additional areas where hardening can be improved to prevent bugs from occurring or being exploited in the future.

These can require more thought than a simple code fix sometimes. Components with known vulnerabilities that aren’t immediately exploitable are a good example of a security hardening fix. Yes, it’s a good idea to update to the next secure version to eliminate the risk of the vulnerability becoming exploitable in the future with code changes; however, are we actually recommending a complete rewrite away from a deprecated JavaScript front-end framework?

Denis has been dragging his heels on his own VueJS2 to VueJS3 migration development project…

Various security hardening controls can often have trade-offs with user experience, functionality, and other side-effects. What is the impact on user experience? Does enabling the control break functionality? Are there operational costs? Does the security benefit outweigh the time investment and user impact? Part of triaging hardening findings is determining if the additional hardening measure is worth the effort and other impacts given your specific threat model and use cases.

A good example: TLS certificate pinning in mobile applications. More often than not, with a robust underlying PKI verification strategy, enabling TLS pinning in a mobile application is more overhead and potential for outages than it’s worth. Depends on the application’s purpose and threat model, of course. No one-size-fits-all, and sometimes an “I understand the issue, but, we’re not going to do that” is a valid response to a hardening finding.

If you decide to move forward, implement the recommendations which make sense for your environment. Then confirm the hardening control has been applied.

If a partial control is being applied, call that out explicitly. Document what was implemented, what wasn’t, and why. This is critical for confirmation testing and for your own records.

I’m a big fan of compensating controls when the full fix isn’t practical. A login rate limiter that blocks 90% of brute-force attempts is better than no rate limiter at all, even if it doesn’t cover every edge case. I’ll take Email/SMS MFA over no MFA any day of the week and twice on Sunday (the gap here being U2F/Passkeys being technically superior). Document the gap, and revisit it later.

Architecture

Architectural findings are usually the hardest to “fix”. These are inherent in the design of the system and are artefacts of the technology or design choices. Complete remediation can sometimes require a redesign or migration to a different platform, which may have its own architectural flaws.

Compensating controls and workarounds are the name of the game here. The goal is to increase understanding of the issue and implement controls that reduce the likelihood of exploitation. This might mean additional monitoring and alerting, access restrictions, network segmentation, or operational procedures. The Entra Primary Refresh Token exploitation by attackers who have compromised an endpoint is a good example here. Is it an attack vector? Yup. Is there a solid control we can enable to fix it? Not really. By and large it’s an artefact of using Entra ID. What do we do about that?

If you decide you don’t want to fix it, or the security value proposition doesn’t make sense, then ensure you document your decision. This is where a risk register comes in.

Client: “We can’t fix this architectural issue. It would cost too much and break too many things.”
Me: “Yeah that’s all good, just know the exploit path is potentially there”
Client: “So we just… accept it?”
Me: “Pretty much! Let’s look at some compensating controls, but otherwise this is going to need to go on the risk register, and we can revisit as we know more.”

I have also had clients come back many months later with a marvellous tale of ditching a whole platform and rearchitecting the solution. In these instances, I’ve been assured that there were multiple other factors, and the penetration testing report wasn’t the only problem. Regardless, feels good to contribute, and it’s a good reminder that we can actually see and understand our systems well enough to make big decisions about how we use them.

Remediation Notes

Good remediation notes make confirmation testing efficient. They should be concise, technical, and focused on the specific finding. We’re ideally looking to hit the following marks:

  1. Show the vulnerable condition before remediation with a screenshot, output from a tool, or whatever is appropriate. If the penetration testing report is decent, it should give you these steps.
  2. Explain how the fix/compensating control was implemented. Provide a link to any pull requests or commits for code, and examples of modified configuration files.
  3. Ideally show the resolved condition with the original test case, confirming the fix works as we think it does. Much like step 1, this could be a screenshot or output from a tool.

The main idea is to show your work along with enough evidence and links that someone else can see how the bug was addressed without having to go digging through the codebase using best guesses. Remediation notes are also a good time to talk about any additional checks you’re putting in place!

Below are some examples of what I think good remediation notes look like for each finding type. I’ve tried to make the examples a little non-trivial to show something closer to real-world examples.

These examples are loosely based on real engagements and findings.

Bug Finding - Insecure Authorisation Controls

Finding: 1.3 Insecure Authorisation Controls on Records Endpoint (HIGH)
Date: 2026-07-15
Owner: Application Dev Team

Authenticated as user j.smith@healthcare.example.com and accessed own patient record:

   $ curl -s -H "Authorization: Bearer <j.smith.token>" \
     "https://app.example.com/api/patients/12345/records" | jq .
   {
     "patient_id": "12345",
     "name": "John Smith",
     "diagnosis": "..redacted..",
     "medications": [..redacted..]
   }

Changed the patient ID to access another patient's record which returned successfully
 with a 200 OK:


   $ curl -s -H "Authorization: Bearer <j.smith.token>" \
     "https://app.example.com/api/patients/12346/records" | jq .
   {
     "patient_id": "12346",
     "name": "Maria von Trapp",
     "diagnosis": "..redacted..",
     "medications": [..redacted..]
   }

Root cause identified in src/middleware/auth.go:87 the authorization middleware validates
the session token but did not verify the requesting user has ownership or clinical access
rights to the referenced patient ID.

Same missing ownership check found on 8 endpoints across the patient portal 
(/api/patients/:id/records, /api/patients/:id/notes, /api/patients/:id/results, 
/api/patients/:id/visits, and 4 more). This is a repeating pattern, not an edge case.

Fix Applied: 

Added ownership validation middleware (src/middleware/resource_auth.go). Applied to all 
8 affected endpoints. PR: https://github.com/org/healthcare-app/pull/245

Added to CI/CD pipeline: CodeQL rule no-direct-object-reference.yaml that flags endpoints
accepting resource IDs without ownership verification. 
PR: https://github.com/org/healthcare-app/pull/247

Confirmation: 

Re-issued the same requests after deployment. The authorization check now correctly 
denies access and:

   $ curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer <j.smith.token>" \
     "https://app.example.com/api/patients/12346/records"
   404

Own patient record still accessible as expected:

   $ curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer <j.smith.token>" \
     "https://app.example.com/api/patients/12345/records"
   200


All 8 endpoints verified with the same pattern. CodeQL rule triggered on the other vulnerable
cases, confirming automated detection is functioning.

- LINK TO THE PR
- LINK TO THE NEW CODEQL RULE
- LINK TO AN EXAMPLE CODEQL DETECTION AND REMEDIATION

Hardening Finding - Missing Authentication Rate Limiting

Finding: 1.2 Missing Rate Limiting on Authentication Endpoints (MEDIUM)
Date: 2026-07-15
Owner: DevOps

No throttling or bot-detection (CAPTCHA) was triggered on repeated login attempts.

Repro:

Issued 200 login requests in 30 seconds against the authentication endpoint, then 
issued a successful login request. All requests were accepted and processed without 
throttling:

  $ for i in $(seq 1 200); do
      curl -s -o /dev/null -w "%{http_code} " \
        -X POST "https://app.example.com/api/auth/login" \
        -H "Content-Type: application/json" \
        -d "{\"email\":\"test$i@example.com\",\"password\":\"wrong\"\}"
    done

  200 200 200 200 200 200 200 200 ... (200 x 200)

  $ curl -s -o /dev/null -w "%{http_code}" \
        -X POST "https://app.example.com/api/auth/login" \
        -H "Content-Type: application/json" \
        -d "{\"email\":\"admin@example.com\",\"password\":\"correct-test-pass\"\}"
  200

Assessment:

The login endpoint is behind Cloudflare WAF, which provides some baseline protection. 
The application also sends email alerts on failed login attempts, which adds a detection 
layer but no prevention.

Decision: Partial fix.

Cloudflare WAF rule - Added managed rule cf-auth-rate-limit to block IPs exceeding 100 
login attempts per 5 minutes. S`till vulnerable to attacks using many IPs (e.g. botnets).`

Bot detection on failed attempts was not implemented: Deferred until UX team can implement 
a user-friendly integration.

Evidence:

Re-issued the same 200-request curl loop, requests beyond 100 attempts in 5 minutes now 
blocked:

  $ for i in $(seq 1 20); do
      curl -s -o /dev/null -w "%{http_code} " \
        -X POST "https://app.example.com/api/auth/login" \
        -H "Content-Type: application/json" \
        -d "{\"email\":\"test@example.com\",\"password\":\"wrong\"}"
    done
  200 200 200 200 200 200 200 200 200 200 200 200 200 200 200 429 429 429 429 429

The Retry-After header is present on 429 responses:

  $ curl -s -I -X POST "https://app.example.com/api/auth/login" \
    -H "Content-Type: application/json" \
    -d "{\"email\":"test@example.com\",\"password\":\"wrong\"}"
  HTTP/1.1 429 Too Many Requests
  Retry-After: 42
  Content-Type: application/json

Risk reassessment date: 2027-01-15
Owner: Backend Engineering Team

- LINK TO CF AUTH RULE DEFINITION
- https://developers.cloudflare.com/waf/rate-limiting-rules/

Architectural Finding - Entra Primary Refresh Token Exploitation

Finding: 1.5 Credential Access - Entra Primary Refresh Token Exploitation (MEDIUM)
Date: 2026-07-15
Owner: Identity and Access Management Team
Risk register entry: RR-2026-041

An attacker who compromised one of our Entra ID enrolled devices can harvest session 
tokens for any service we authenticate to with Entra (Outlook, SharePoint, OneDrive, etc)

Reproduction:

Confirmed the attack path with browser dev-tools. Finding details are accurate and 
replaying authentication tokens from an Entra enrolled device granted remote access to 
services without having to perform authentication.

Decision: Accept with Compensating Controls

This is an architectural limitation of Entra ID's connected device and SSO design. The 
PRT model prioritises seamless single sign-in over defence-in-depth. There is no product 
configuration to disable this behaviour without breaking SSO entirely.

Full remediation is not supported by Microsoft. The following compensating controls were 
implemented to reduce the attack surface and improve detection:

Detection rules for PRT replay - Added detection rules for anomalous sign-in patterns 
consistent with PRT replay:

 - Sign-in from an OS/platform not previously associated with the user (e.g., Linux UA 
for a Windows user)
 - High-volume access to multiple Entra-protected resources from a single token session

Rules routed to SOC for investigation. Initial testing confirmed detection of the reproduction
scenario described above. Noted a skilled attacker could likely bypass this alerting with 
fraudulent user agents.

Assumption baked into incident response:

Updated the incident response playbook: any confirmed workstation compromise is treated as 
compromise of all Entra-authenticated services accessible to that user. Automated response: 
revoke all sessions via Revoke-SPOUserSession, force password reset, and rotate any 
service-linked credentials.

What cannot be done:

 - Disabling PRT: Would break SSO for all Microsoft 365 services, Intune management, and 
Entra-authenticated third-party applications. Not viable.
 - Device-bound PRT: The PRT is not cryptographically bound to the issuing device in a way
that prevents replay. Microsoft has not provided a remediation path.

Remediation Notes - Summary

The best bit of advice I can give for writing the remediation notes is the same we give the team at Pulse for writing the technical details in the reports. Imagine the reader is future-you, has a patchy memory of the system, and needs to pick the work back up quickly.

If you show your work with evidence like screenshots and links to pull requests/config files, briefly explain your decisions, and include any info you think might be helpful for others assessing the remediation, you’re golden!

My examples were pretty lengthy. The remediation notes don’t always have to be so verbose. If it’s a simple bug with a simple fix, a few simple sentences and some simple evidence is probably fine.

Engaging Confirmation Testing

Confirmation testing verifies remediation has been applied correctly, and the vulnerabilities are resolved. To engage with confirmation testing, you’ll generally contact your penetration tester with a list of findings you’d like rechecked, and they’ll provide an estimate on costs and how long that’ll take.

How you approach this process makes a big difference to the efficiency and cost of the engagement.

Receiving an email which says “plz retest” after delivering a report is about the same as receiving an email which says “plz fix”. The tester has to re-learn the system, figure out what changed, and test whether the fix works. The process is expensive and slow, and the more time that’s passed the longer it takes the consultant to get back up to speed and start doing meaningful analysis.

A better approach is to include remediation notes above for each finding. Providing this information lets the tester determine remediation status quickly. They’re basically confirming your work, rather than starting from scratch. The approach reduces confirmation testing time and makes the process more cost-effective.

I have a couple of clients now that provide remediation notes so thorough I can practically confirm every finding in half the expected time. They’d reproduced each finding, documented the fix with code snippets, and included screenshots showing the resolved state. Good remediation notes look like this.

Some clients now complete their own confirmation testing internally. If your team can reproduce the finding, implement the fix, and verify the fix works… maybe you don’t feel the need to engage the pentesters again. The pentester’s report becomes your testing guide, and your remediation notes become the evidence.

If you’re happy, I’m happy. See you next time, call me if you have questions!

The rest of this article is going to talk about some other concepts connected to remediation security findings.

The Risk Register

Excuse me while I clamber onto my soap box… I’m going to say something controversial for a technical offensive security person. I actually like the risk register.

Risk registers get a bit of a “risk accepted” joke in the cyber-security community sometimes. The meme is that organisations find vulnerabilities, run out of time/money/care and decide to accept the risk as a way of dodging responsibility, then never revisit the decision. A risk register becomes a graveyard of ignored findings.

Jokes aside, a good risk register tool is great. The register gives you something to look at over your morning coffee, ponder the decisions of the past, and regularly re-assess to make sure you’re happy with the risk statuses and where you’re at right now. The technology is going to change and attacker techniques will adapt, with a good document detailing decisions and compensating controls you can make faster judgements as new information comes to light.

From a technical cyber-security perspective, each risk entry should capture at least:

  • The finding and its severity
  • The attacker-type and threat model that the finding/condition is concerned with (compromised team member, external attacker, etc)
  • Why the decision was made to accept, defer, or mitigate the risk
  • What compensating controls are in place
  • When the decision should be re-assessed
  • Who owns the decision
  • Risk score, residual risks, and all that other good stuff that goes into a risk register that’s outside of the strictly technical sphere.

Regular re-assessment is what separates a useful risk register from a place where vulnerabilities go to be forgotten (and possibly exploited at a later time). Technology changes, threat landscapes evolve, and what was acceptable six months ago may not be acceptable today. What was painful to fix yesterday may have an easier solution today.

I’d also suggest making the register available to your teams. No one person understands all the complexities of a modern computing environment, and many minds working together make light work of complex problems. Giving your colleagues the opportunity to understand the decisions and comment on the specifics helps us all improve.

Outliers Versus Repeating Patterns

We touched briefly on outliers versus repeating patterns when it comes to vulnerabilities.

Here’s the truth: a penetration test can rarely tell you definitively whether a bug is an edge case or a pattern. Especially if the tester explored a subset of your system over a limited time window. A single instance of SQL injection might be a one-off mistake by a developer, or the tip of an iceberg. Was that network port with a vulnerable service an unfortunate bit of shadow IT, or a sample of a wider network with missing patch management processes?

Triage turns pentest findings into actionable investigations. The report should give enough background and context to understand the vulnerability well enough to investigate for yourself. Reproducing the finding, understanding the root cause, and then searching your codebase or wider environment for similar patterns is the pro move here.

Searching for patterns can be a double-edged sword, though. Treating a repeating pattern as a single edge case and patching only the one instance leaves other potentially exploitable conditions untouched. The next annual penetration test will find the same vulnerability in a different endpoint, and we repeat the same dance all over again. Meanwhile, the underlying pattern continues into the codebase because the root cause was never addressed.

On the other hand, treating a genuine edge case as a systemic pattern wastes time and resources. Building automated checks and retraining teams for a one-off mistake isn’t efficient either. Implementing a pattern-level fix might take weeks or months, when a targeted fix and a quick code review would have solved the problem in an afternoon.

So what’s the practical approach? It depends! If the finding is a repeating pattern, that’s when automated tooling becomes valuable. Pentest findings can become checks for your linters, CI/CD tools, static code analysis rules, and other automated tooling. If a finding represents a pattern that could reoccur, the best longer-term protection is building automated detection into your development pipeline. For example, if the pentest found unsafe string concatenation in SQL queries across multiple endpoints, the fix is to write a static analysis rule or linter check that catches the pattern, add it to your CI/CD pipeline, and prevent it from being introduced again. These checks may even catch it in other places in your codebase that may not have been found up to this point.

If it’s just one endpoint? In my opinion, patch that endpoint, consider why it happened, and move on.

It’s all a balancing act.

Developer Training and Shift-Left Practices

One thing I like about targeted security review documents, like pentest reports, is they’re specific for the target. These docs are fantastic training material! Instead of generic security awareness training covering everything and focusing on nothing, you can use report results to teach the exact vulnerabilities your codebase faced. If you’re super fancy you could even turn these into internal training labs.

If the pentest found a cross-site scripting issue, use that finding as a concrete example in your next security training session. Show the developers the exact endpoint that was vulnerable, explain why it’s dangerous, and walk through the fix. Real examples from your own codebase are more effective than theoretical scenarios pulled from an online training program.

The same applies to other finding types. A broken access control becomes a lesson on authorisation checks. A misconfigured cloud resource becomes a lesson on infrastructure hardening (probably with a sidebar on automated infrastructure-as-code scanning); injection vulnerabilities become a great time to discuss input-based attacks and how untrusted data is handled. Each finding is a teaching moment.

This is where shift-left security works, trying to get security issues identified and resolved earlier in the development lifecycle. When techs understand the vulnerabilities they’ve personally experienced, they start thinking about security earlier in the development lifecycle. They start asking “Could this be exploited?” before writing the code or deploying the service, rather than after the pentester finds it. The upskilling and investment in the team is worth more than any tool or process. Terms like SQL Injection and Brute Force Attack stop being security meetup trivia and actually mean something.

Pentesting findings can also become automated checks like we discussed in the patterns section. Dependabot becomes a thing we all strive to appease now.

Some teams take this further and establish security champions programs. Champions programs identify internal techs interested in security and have them act as security advocates within their teams. The champions answer security questions before they become vulnerabilities and help spread security awareness organically.

I have mixed feelings about the champions programs, though. This whole cyber-security field is dense and complex, and isn’t really something you can tack onto the side of someone’s day-job and expect good results. If you have security champions, make sure they have enough time and support to succeed in that part of their role.

None of this replaces a penetration test, though. Automated checks and internal advocacy can catch common issues but miss the creative attack paths a skilled tester will find. They do reduce the number of repeat findings at your next annual pentest, which also frees up the expensive external tester to spend their precious time looking for complex and meaningful vulnerabilities that require expert analysis. A good return on investment.

Wider Business Concerns

This article covered the technical side of remediation, but other business aspects also shape how organisations handle post-pentest findings. SLAs and time-to-fix metrics determine how quickly vulnerabilities need to be addressed based on severity and business risk. Post-remediation monitoring ensures fixes remain effective and lets the SecOps folks get involved with real-world data. Third-party relationships and vendor coordination come into play when the bug is in someone else’s system or code. Quality indicators and security metrics help track remediation effectiveness over time and report progress to stakeholders.

These topics all deserve their own deep dives. A penetration tester is best positioned to advise on finding and remediating technical vulnerabilities. The wider business concerns like SLAs, vendor management, metrics, strategic planning, are super important and belong in a larger discussion.

Summary

After a penetration test report is delivered, the work of improving the system begins. Find the stakeholders, reproduce the findings, implement fixes based on the finding type, and document the remediation. Use a risk register to track longer-term decisions, and look for repeating patterns that can become automated checks. Get proficient enough at this process, and you might find you start engaging external security vendors less often to check your remediation work.

When it comes to confirmation testing, providing detailed remediation notes so the tester can verify your work quickly is a great idea. You’ll also both be working from a shared base understanding. Some teams are comfortable doing their own confirmation testing internally, a valid approach if the findings can be reproduced and verified.

This is how penetration testing findings become a long-term investment in your security program rather than a one-time remediation task. And this is where the real value of penetration testing starts to compound: the upskilling of your internal teams. Every finding reproduced, every fix implemented, every pattern identified becomes hands-on security training for your people. Next thing you know, maybe your team starts spotting some of these issues before you even call the pentesters.

The goal of penetration testing is to improve the security of your systems. The report is just the starting point. What you do with it matters most!

That’s all, folks!

This is the last article in the Purpose and Execution of Penetration Testing series, the other three are linked below.

I’ve really enjoyed writing these articles and thinking deeply about how cyber-security reviews work. Huge thanks to the various amazing clients I’ve worked with who have had input into this process. You know who you are, and I appreciate you.

I guess there is some truth in that old adage that if you want someone to really understand something, make ’em show someone else how to do it! I should write a book…


Follow us on LinkedIn