Writing Remediation a Developer Will Actually Action
"Implement input validation" is not remediation, it is a category. What a developer needs from your finding, how specific to be without writing their code for them, and what to do when there is no clean fix.
The description is the part testers enjoy writing and the part clients skim. The remediation is the part that decides whether the finding is still open in six months, and it is routinely the weakest paragraph in the report.
The failure is rarely ignorance. It is that remediation gets written last, at the end of a long day, by somebody who has already proved the point to themselves and is now describing it to a reader they cannot see. What comes out is a category name where an instruction should be.
The advice that gets ignored
"Implement proper input validation." "Ensure access controls are enforced." "Follow the principle of least privilege." Each of these is true, none is actionable, and a developer reading them learns only that you did not want to be pinned down.
Worse, they are unfalsifiable. A developer can add a length check, call it input validation, and close the ticket. You will find the same injection on the retest, and the argument that follows will be about whether they did what you asked, because what you asked for did not say.
Name the location, not the class
The person fixing this needs to know where to go. Not the vulnerability class, which they can look up, but the parameter, the endpoint, the file where the pattern lives if you saw it, and whether the same pattern appears elsewhere.
"The account_ref parameter on GET /api/v1/accounts is concatenated into the query" tells a developer where to open their editor. "SQL injection is present in the application" starts a search that may take them a day and may end somewhere you did not test.
Where the same weakness appears at several locations, list them. A remediation that fixes one of five instances is a remediation that will be marked complete.
Give the fix at the level they can apply it
There is a level of specificity that helps and a level that is presumptuous, and the line sits at the point where you would need to know their codebase. Say what the correct pattern is; do not write their function.
- Useful: "Use a parameterised query so the value is never part of the SQL string. In this framework that is the query builder rather than string interpolation."
- Presumptuous: a fifteen-line code sample using a library they may not have, in a style their codebase does not use.
- Useless: "Sanitise user input before use."
If the framework has a documented safe way to do the thing, name it. That single sentence saves a developer the half hour of deciding which of four approaches you meant, and it moves the conversation from whether to how.
Say what you would accept as fixed
This is the sentence most reports are missing, and it is the one that makes a retest fast. State the observable condition that means the finding is closed.
"Fixed when the same request returns the same response for a valid identifier and a 403 for an identifier belonging to another tenant" is a criterion. Both sides can check it, neither can argue about it, and the developer knows when to stop.
It also protects you. A finding without a closure criterion is one where the client decides what fixed means, and they will decide generously, because they are the ones under pressure to close it.
When there is no clean fix
Sometimes the correct answer is architectural and the client cannot do it this quarter. Pretending otherwise produces a remediation nobody will attempt, which is worse than an honest one they will.
Give the real fix first, then the mitigations, ranked, with what each one does and does not buy. A rate limit in front of an enumeration weakness reduces the volume an attacker gets and does not remove the weakness, and saying so is the difference between a mitigation and a false sense of completion.
Where the client has already accepted the risk, that belongs in the finding as a decision with a name and a date attached, not as a softened remediation. Softening the advice to match a decision is how a report stops being evidence of anything.
Do not paste the vendor page
A remediation section that is three paragraphs of copied guidance and one line of your own is transparent to anybody who has read the guidance. It also ages: the link rots, the vendor reorganises, and your report now cites something that says something else.
Cite the reference, summarise the part that applies here, and write the rest yourself. What the client is paying for is the judgement about which part applies to them, and that is the part a copied page never contains.
Order matters more than completeness
A findings list with nineteen remediations and no order is a list that gets worked from the top, which is usually the order you happened to write them in. If the third item is the one that closes off the path to customer data, it should not be third because of when you found it.
Order by what the fix removes, not by severity label alone. Two Highs are not equivalent when one breaks a chain and the other is an isolated weakness on a system nobody can reach. Where a single fix closes several findings, say so in each of them, because that fix has just become the cheapest thing on the list and nobody can see that from the individual entries.
Where sequencing matters technically, state it. Rotating a credential before you have fixed the leak that exposed it is work that will be done twice, and a developer following a list top to bottom has no way to know that from the findings alone.
Write it for the person who did not read the description
The remediation is the section most likely to be read in isolation. It gets pasted into a ticket, forwarded to a team that was not on the call, and read by somebody who has the fix to make and no interest in how it was found.
That means it has to carry enough context to stand alone: what is wrong, where, and what correct looks like. Not the whole description again, but not a sentence that only parses if you have just read three paragraphs above it. "Fix this by parameterising the query" is meaningless in a ticket; "the account_ref parameter on this endpoint is concatenated into SQL, so parameterise it" survives the journey.
A useful habit is to read only your remediation sections, in order, as if you were the developer. Anything that does not make sense on its own gets one more clause. It takes ten minutes and it removes most of the follow-up questions you would otherwise field a fortnight later.
Remediation is one of the fields the knowledge base carries, so the version your firm has argued about is the one that arrives on the next finding, with the instance specifics left to be written. Where you generate a first draft, it is written against a prompt you can read and edit rather than a hidden one, and the draft is a starting point that a tester still owns.
Pental Is Built by the People Writing This
Engagement management for testing firms, on a database you own, under your brand, with the AI running on your key.