Before the report, Part 2: writing it so someone can act on it

A report that cannot be acted on is a complaint. Three things make a vulnerability report actionable: reproduction steps, impact, and a hint at the fix. Everything else is optional.


Assume you have done the work from Part 1: the code path exists, the PoC reproduces, you know what the impact is. Now you have to write it down in a way that causes someone else to fix it. That is the only purpose of a vulnerability report. Not to demonstrate expertise, not to establish priority, not to describe a problem elegantly. To cause a fix.

Writing for that purpose requires thinking about the reader. The reader is an engineer on a security team. They receive reports all day. They need to triage yours quickly, assign it correctly, reproduce it reliably, and understand what a fix looks like. Your job is to make all of those things as easy as possible.

Reproduction steps: the only non-negotiable section

If the recipient cannot reproduce the issue from your report, they cannot fix it. This is the only section of a vulnerability report that is truly mandatory. Everything else can be inferred from a good reproduction case. Nothing can be inferred from a reproduction case that does not work.

Write reproduction steps as if you are writing them for a competent engineer who has never heard of your finding before, has never read your other work, and has exactly enough time to follow the steps and observe the result. Numbered. Specific. Include the version of the software you tested against. Include the output you observed, verbatim, so the reader can recognise when they have reproduced the issue and when they have missed it.

Test your reproduction steps by following them yourself, from a clean environment, before you send the report. It is very common to write reproduction steps that skip a prerequisite that you have set up once and forgotten about. Your clean environment will find these omissions. The security team's clean environment will also find them, and they will email you, and this slows everything down.

Impact: precise, not dramatic

State what an attacker can achieve, from what position, with what prerequisites. One paragraph. No adjectives that do not add information. "An unauthenticated remote attacker can cause a denial of service by sending a malformed packet to port X" is useful. "This critical vulnerability could potentially allow sophisticated threat actors to completely compromise affected systems" is not. One of those sentences helps an engineer triage. The other describes a film.

A hint at the fix

You are not responsible for fixing the issue. But if you can see what the fix looks like — if the missing check is obvious, if the bounds condition is apparent from your analysis — say so. Not prescriptively, and not in a way that commits the vendor to a specific approach. Just: "the issue appears to be that X is not checked before Y; a bounds check here might address it." A sentence or two.

This is courtesy extended to the engineer who has to implement the fix. They will likely arrive at the same conclusion independently. Your observation saves time. It also demonstrates that you understand the code well enough to have an opinion, which tends to be taken seriously.

What to leave out

Long introductions. Your biography. The history of similar vulnerabilities in unrelated software. Extended speculation about attacker motivations. Requests for timelines. Demands of any kind. All of these make the report longer and the engineer's job harder. The report should be the shortest document that contains everything necessary to understand, reproduce, and fix the issue.

A vulnerability report is a message to a specific person asking them to do a specific thing. It succeeds or fails on whether that person can act on it. Write for the engineer, not the audience. The PING is only useful if it produces a return — and returns require clarity.