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/export allows 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/export allows any authenticated user to download another user’s billing history

Summary: The /account/export?user_id=X endpoint does not verify that the requesting user’s session matches the user_id parameter. 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. Change user_id to a sequential neighbouring ID (Account B). 4. Observe the response returns Account B’s billing history without any authorization error.

Professional Tips

  1. 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.
  2. Always attach evidence, even for “obvious” bugs. A screenshot or request log removes any ambiguity and speeds up triage significantly.
  3. 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

  1. Rewrite this vague finding into a structured report: “the export endpoint leaks other people’s data if you change the ID in the URL.”
  2. Write a two-sentence impact statement for a cross-site scripting (XSS) vulnerability found on a public comment form.
  3. Draft a polite follow-up message asking for a status update on a report submitted three weeks ago with no response.