How to Write a Bug Bounty Report in English
A practical English guide for writing clear, well-structured bug bounty and vulnerability reports that get triaged quickly and taken seriously by security teams.
A bug bounty report has one job: convince a security team, quickly and unambiguously, that a real vulnerability exists and needs fixing. Vague, poorly structured reports get deprioritised or bounced back with clarifying questions — wasting time on both sides and sometimes losing the reporter their payout entirely. Whether you’re submitting through HackerOne, Bugcrowd, or a private program, the English you use directly affects how seriously and how fast your report gets triaged.
Key Vocabulary
Proof of concept (PoC) — a minimal, reproducible demonstration that the vulnerability actually works, not just a theoretical description.
“I’ve attached a proof of concept script that demonstrates the SQL injection against the /search endpoint using a single crafted parameter.”
Reproduction steps — the exact, numbered sequence of actions needed to trigger the vulnerability, written so anyone can follow them without guessing.
“Reproduction steps: 1) log in as a standard user, 2) navigate to /account/export, 3) intercept the request and change user_id to a different account’s ID, 4) observe that the response returns that account’s private data.”
Impact — a clear statement of what an attacker could actually achieve, avoiding both understatement and exaggeration. “Impact: any authenticated user can read any other user’s billing history by changing a single numeric parameter — no additional privileges required.”
Severity — your assessment of how serious the issue is, ideally backed by a recognised framework like CVSS rather than a subjective label alone. “Based on the CVSS 3.1 vector I’ve calculated, this scores 8.1 (High) — primarily due to the low attack complexity and confidentiality impact.”
Attack scenario — a short narrative describing how a real attacker would realistically exploit the issue, which helps a triager who wasn’t expecting this specific bug class. “In a realistic attack scenario, a malicious user could enumerate sequential IDs and exfiltrate billing data for the entire customer base within minutes.”
Remediation suggestion — an optional, non-mandatory recommendation for how the issue could be fixed, which triagers appreciate even if they don’t use your specific suggestion.
“As a remediation suggestion, validating that user_id in the request matches the authenticated session would close this specific vector.”
Structuring the Report
- Title: a one-line summary stating the vulnerability class and affected endpoint — “Insecure Direct Object Reference (IDOR) in
/account/exportallows cross-account data access.” - Summary: two to three sentences giving the triager the whole picture before they read further detail.
- Steps to reproduce: numbered, specific, and complete — assume the reader has zero prior context on this endpoint.
- Impact: what an attacker gains, stated plainly without hedging or inflating.
- Suggested severity: your CVSS score or equivalent, with the reasoning behind it.
- Supporting evidence: screenshots, request/response logs, or a short video — attach, don’t just describe.
Common Mistakes
- Overstating impact: “This could bring down the entire company” for a low-severity issue damages your credibility for future reports. Match the language to the actual, demonstrated impact.
- Vague reproduction steps: “Just try changing the ID and it works” forces the triager to reconstruct your exact steps, which delays or kills the report.
- Skipping the proof of concept: a report that only describes a vulnerability theoretically, without demonstrating it, is far more likely to be marked “informative” (not eligible for a bounty) rather than “confirmed.”
- Using aggressive or accusatory language: “Your security team clearly didn’t test this” invites a defensive response rather than a fast fix — stick to neutral, factual language.
A Sample Report Opening
Title: IDOR in
/account/exportallows any authenticated user to download another user’s billing historySummary: The
/account/export?user_id=Xendpoint does not verify that the requesting user’s session matches theuser_idparameter. By changing this value, any authenticated user can download another account’s full billing history, including invoice amounts and payment method’s last four digits.Steps to Reproduce: 1. Log in as any standard account (Account A). 2. Send a GET request to
/account/export?user_id=<Account A's ID>and note the response is your own data. 3. Changeuser_idto a sequential neighbouring ID (Account B). 4. Observe the response returns Account B’s billing history without any authorization error.
Professional Tips
- Lead with the summary, not the exploration story. Triagers read dozens of reports a day — get to the point in the first two sentences before narrating how you found it.
- Always attach evidence, even for “obvious” bugs. A screenshot or request log removes any ambiguity and speeds up triage significantly.
- State your assumptions explicitly. If your test relied on a specific account tier or a particular browser, say so — it saves the triager a round of clarifying questions.
Practice Exercise
- Rewrite this vague finding into a structured report: “the export endpoint leaks other people’s data if you change the ID in the URL.”
- Write a two-sentence impact statement for a cross-site scripting (XSS) vulnerability found on a public comment form.
- Draft a polite follow-up message asking for a status update on a report submitted three weeks ago with no response.