The engagement: methodology and reporting
Log in Join

Lesson 4 · Reading · 25 min

Writing the report that survives triage

Your finding does not exist until someone else can reproduce it from your words. The report is the deliverable, the only part of the work a client pays for, a program rewards, or an exam grades. A brilliant bug in a bad report is a closed ticket. This lesson is how to write one that lands on the first read.

The sections of a bug report that survives triage

The one job of a report

A report has a single job: let a busy stranger reproduce your finding and understand its impact, without asking you anything. A triager reads dozens of reports a day. If yours makes them work, vague steps, no raw request, unclear impact, they close it or push it back, and your real bug dies in the queue. Write for that reader: tired, skeptical, short on time, and about to decide your finding's fate in ninety seconds.

The sections

A report that survives triage has these parts, and the shape is standard across bug bounty and consulting:

  • Title. Bug + location + impact, in one line: "IDOR in /api/invoices lets any user read another's invoices". Not "found a bug".
  • Summary. Two or three sentences: what the vulnerability is, where, and why it matters.
  • Affected asset / scope. The exact URL, endpoint, or component, and a note confirming it is in scope. This is the first thing a triager checks.
  • Steps to reproduce. Numbered, exact, and complete. A stranger following them must hit the bug every time. Include which account, which request, what to observe.
  • Proof of concept. The raw evidence: the actual HTTP requests (copy-pasteable), the response that proves it, screenshots where visual. For access bugs, both accounts' requests side by side.
  • Impact. What an attacker actually gains, "read any user's financial records", "execute commands as the web-server user", tied to what you demonstrated.
  • Severity / CVSS. A defensible rating (below).
  • Remediation. How to fix it: parameterised queries, an ownership check on the object, output encoding, session rotation on login. It shows you understand the bug and helps the fix land.

Steps and proof: the part that decides everything

Most rejected reports die here. Make the steps mechanical:

  1. Log in as user A (alice). Open your invoice; note the URL /api/invoices/1042.
  2. Log in as user B (bob) in a separate session.
  3. As B, request GET /api/invoices/1042 (raw request below).
  4. Observe: the response returns user A's invoice, though B does not own it.

Then paste the raw requests and responses. A triager who can copy your request into their own tool and see the same result approves the report; one who has to reconstruct it from prose does not. Two accounts, two requests, one clear crossing, that is a perfect access-control PoC.

Severity you can defend

Rate impact honestly and consistently. CVSS is the common scoring framework; it turns properties of the bug (attack vector, complexity, privileges required, impact to confidentiality/integrity/availability) into a number and a severity band. Use it as a shared language, but the number must match what you proved:

  • Do not inflate. A self-XSS or an info leak is not "critical" because you wish it were; inflating severity is the fastest way to lose a triager's trust for every future report.
  • Do not deflate a real one. A cross-account read of financial data is high; say so.
  • Justify it in a sentence: attacker position, what they reach, what they gain. A rating with reasoning is defensible; a bare number is arguable.

Honesty, again, in writing

The report is where the honesty gate is most visible and most consequential. Claim exactly what you reproduced (revisit the previous lesson's diagram): "Bob read Alice's invoice, both accounts mine", not "leaks all users" if you tested one. If something is unconfirmed, label it: "the version indicates a known RCE; not reproduced." Triagers reward precision and remember exaggeration. One honest, tightly-scoped report builds more reputation than three inflated ones.

Before you submit: the duplicate and scope check

Two last checks save everyone time. Scope: re-confirm the asset and the vulnerability class are in scope and not excluded (the last lesson). Duplicates: on a bounty program, a common bug on a public target may already be reported, skim the program's known-issues and disclosed reports first. A well-written report of a duplicate still gets closed as a duplicate; spend your effort where it is novel.

Your exercise

Pick a bug you solved in one of this track's labs and write it up in full, using the sections above, as if submitting to a program: title, steps, raw PoC, honest impact, a CVSS rating with one line of justification, and a remediation. Then read a few real disclosed reports on a public bug-bounty platform and compare, notice how the strong ones are reproducible and precise, and how they never overclaim. This platform's report-writing guidance goes deeper on the triage-survival specifics.

Where this goes next

You can find, prove, scope, and report. The final lesson puts it under a clock: how to approach a practical exam day, planning your time, working the methodology, and turning a fixed number of hours into findings and a report that pass.

This lesson has 1 lab to try what you just read.