Writing a Vulnerability Report That Gets Taken Seriously
Finding a vulnerability is half the work. The other half is convincing a busy stranger that it is real, that it matters and how to fix it, in a few minutes. A clear, honest, reproducible report gets fixed quickly and builds your reputation. A vague or exaggerated one gets ignored. This lesson gives you a structure and a way of thinking you can reuse in bug bounty, in pentest reports and in your portfolio.
Who reads your report?
Imagine the people on the receiving end:
- A triage analyst who has dozens of reports to read, many low quality. They need to reproduce your issue quickly.
- A developer who must understand the cause and the fix without having your skills.
- A manager who must understand the business impact and priority.
A good report speaks to all three: a short summary for managers, precise steps for analysts, and a clear recommendation for developers.
The anatomy of a good report
- Title: specific and short. "Missing ownership check lets one customer read another's order" is far better than "Security bug in API".
- Summary: two or three sentences covering what the problem is, where it is and what the consequence is.
- Affected asset: the exact address, application, version, environment and role needed.
- Severity and impact: a justified rating and a description of the realistic consequence in business terms.
- Steps to reproduce: numbered, minimal and complete, so that anyone can follow them.
- Evidence: requests, responses and screenshots, with sensitive data removed.
- Expected versus actual behavior: what should have happened, and what did.
- Remediation: a practical suggestion and, where useful, a reference such as an OWASP page.
- Notes: limitations of your test, things you did not check, and confirmation that you stayed within the rules.
An example, from a fictional lab application
Here is a short report about a flaw in a deliberately vulnerable lab application on your own machine. Nothing in it targets a real system.
Title
Order endpoint does not check ownership (lab application)
Summary
The endpoint that returns an order accepts any valid order number
from any signed-in user. A customer can read orders that belong to
other customers by changing the number in the address.
Affected asset
LabShop (local training application), API route /api/orders/{id}
Role needed: any regular customer account
Severity
High in a real application: exposure of other customers' names,
addresses and purchases, with no special tools needed.
Steps to reproduce
1. Sign in as test user A and open one of your own orders.
2. Note the order number in the address.
3. Replace it with a number belonging to test user B.
4. Observe that the response contains user B's order.
Evidence
Request and response attached; personal data redacted.
Expected vs actual
Expected: access denied or "not found". Actual: full order returned.
Recommendation
Check on the server that the order belongs to the signed-in user for
every request. Return the same response for "not yours" and "does not
exist". Consider non-sequential identifiers as an extra layer.
Reference: OWASP API Security Top 10, object-level authorization.
Notes
Tested only with two accounts I created. No other data accessed.
Notice what this report does well: specific title, simple language, a short reproducible path, impact in business terms, a fix and a statement of the limits of the test.
Severity: be honest and be able to justify
Many programs use the Common Vulnerability Scoring System (CVSS), which rates severity using factors such as how the attack is performed, what privileges are needed, whether user interaction is required and the impact on confidentiality, integrity and availability. It is a useful common language, but it is not a calculator that replaces thinking. A flaw's real severity depends on context: the same issue can be critical on a bank's customer portal and trivial in a throwaway demo.
Three honesty rules:
- Do not exaggerate. Triage analysts quickly lose trust in people who label every observation "critical".
- Do not understate either. If you demonstrated access to another person's data, say so clearly.
- Explain your reasoning in one or two sentences: "High, because any customer can read others' personal data without special privileges."
Reproducibility: the quality that matters most
A report that cannot be reproduced is a report that will be closed. Test your own steps from scratch, as if you were someone else, preferably on a clean account. Include:
- The exact starting state: which account, which role, which settings.
- Each action in order, with the exact values changed.
- The expected observation after each important step.
- Any timing or condition that matters.
- The environment: browser or client, date of the test (the application may change).
Evidence without harm
- Redact personal data. Blur or replace real names, emails and addresses in screenshots and logs.
- Remove secrets such as tokens and passwords, or replace them with placeholders.
- Keep it minimal. One request and one response are usually enough.
- Prefer your own test data. Use accounts you created, so that no real person is involved.
- Store evidence securely and delete what you no longer need, according to the program rules.
Common mistakes
- Submitting scanner output as a report. Raw tool output with no validation is noise. Verify manually, explain the real impact and trim the rest.
- Describing theoretical issues without a realistic scenario, such as a missing header with no demonstrated effect, and marking them as critical.
- Burying the problem in long text. Start with the summary.
- Going beyond the scope or the minimal proof, for example by reading more data "just to be sure".
- Hostile or demanding tone. Threats and ultimatums damage you and may be illegal.
- Reporting many weak issues in a single report. Separate distinct problems so that each can be tracked and fixed.
- Spelling and structure neglected. You are not graded on grammar, but a readable report is taken more seriously.
Communicating after submission
- Answer questions promptly and factually.
- If your report is classified as duplicate or not applicable, ask politely for the reasoning and learn from it.
- If you disagree with the severity, explain the impact with concrete facts, once, calmly.
- Never share the details publicly unless the policy allows it and the issue is fixed.
The same skills in a professional pentest report
In a pentest, the report is the deliverable that the client pays for. It adds an executive summary, methodology, scope, a table of findings ranked by risk, detailed findings in the structure above and an appendix with technical details. You saw this in the previous course. The core discipline is identical: clear language, reproducible steps, honest impact, practical fixes.
Your turn: rewrite a poor report
Here is a bad report from a fictional beginner:
Title: HUGE SECURITY HOLE!!!
Your site is not secure. I ran a scanner and it found 47 critical
issues. Pay me or I will tell everyone. Fix this now.
Explain at least five things that are wrong, then rewrite it as a short, professional report for a single, made-up issue: "the password reset page of a lab application reveals whether an email address has an account".
See a solution
What is wrong: a vague, sensational title; no asset or scope information; unvalidated scanner output instead of manual verification; an inflated severity; no steps to reproduce; no impact explanation; no recommendation; and a threat of disclosure combined with a demand for payment, which is unprofessional and potentially criminal.
A better version:
Title
Password reset page reveals whether an email address has an account
Summary
On the password reset page of the lab application, the message
differs depending on whether the entered email address belongs to
an account. This allows anyone to check which addresses are registered.
Affected asset
LabShop (local training application), page /reset-password
Severity
Low to medium: it discloses account existence, which helps targeted
phishing and password guessing, but gives no direct access.
Steps to reproduce
1. Open the reset page, enter an address of an account I created.
Result: "A reset link has been sent."
2. Enter an address with no account.
Result: "No account found with this address."
Expected vs actual
Expected: the same message in both cases. Actual: different messages.
Recommendation
Return a generic message ("If this address is registered, an email
has been sent") and keep response times similar. Add rate limiting.
Notes
Only addresses of accounts I created were used.
Portfolio step
In 06-bug-bounty-community, add sample-vulnerability-report.md: a full report about a weakness you found in your own lab (Juice Shop or DVWA are ideal) following the structure of this lesson. Because it concerns a deliberately vulnerable training application, it is safe to publish. Add a short README line stating that all examples come from training environments. A good sample report is often the single most persuasive item in a beginner's portfolio.
Key takeaways
- Write for three readers: the triage analyst, the developer and the manager.
- Use a clear structure: title, summary, asset, severity, reproducible steps, evidence, expected versus actual, remediation and notes.
- Rate severity honestly and justify it; context matters more than a number.
- Reproducibility is the quality that matters most; test your own steps from scratch.
- Redact personal data, avoid scanner dumps and keep a professional tone, never threats or ultimatums.
In the next lesson, you will look at the certifications that can open doors, and how to choose among them.