Security research
Step 318. Writing a Report That Gets Accepted
Level 4 — Bug Bounty | Difficulty ★★★☆☆ | Estimated time: 3 hours
Prerequisites: you have finished Step 317 (candidate verification). You have 1 valid vulnerability and an evidence file (
evidence_idor.txt) in hand.
- What you need: a text editor, and Step 317’s verification results and evidence file. This chapter is a document-writing project.
- ⚠️ All exercises in this chapter are for your own lab and legal platforms only. Applying them to unauthorized systems is a crime.
- Caution: report only through the program’s official reporting channel, and do not disclose the content externally until it is fixed and cleared for publication (responsible disclosure). The lab’s accounts and data are all fabricated.
The same vulnerability pays differently depending on the report. A triager (report reviewer) reads dozens a day — a report must be "reproducible within 5 minutes by someone with zero context." Today, using the IDOR confirmed in Step 317 as material, you complete one report that passes triage. This is the graduation piece of this Level’s segment.
1. Learning Objectives
By the end of this chapter, you will be able to:
- Explain the standard report structure (summary · reproduction steps · impact · fix suggestion · evidence)
- Point out at least five differences between a bad report and a good report
- Review reproduction steps from the perspective of "someone with zero context"
- Write tier grounds by comparing impact against the reward table
- Write one finished report using the report template
2. Background Knowledge — Today’s Tools and Concepts
Today’s Tools at a Glance
| Category | Details |
|---|---|
| Language/environment | Markdown document writing (editor of your choice) |
| Today’s tools | Report template, (concept intro) HackerOne Hacktivity (browsing disclosed reports) |
| Concepts needed | Reproduction steps, impact description, reward-tier grounds, responsible disclosure |
| Today’s deliverable | 1 finished report_IDOR.md |
2-1. The Standard Report Structure
Input fields differ slightly per platform, but the content skeleton is fixed.
| Section | Role | Length sense |
|---|---|---|
| Title | The vulnerability in one line — [feature][cause][impact] | One sentence |
| Summary | The first paragraph a triager reads | 2–3 sentences |
| Reproduction steps | A numbered list — followable by anyone | 5–10 steps |
| Impact | What an attacker can do with this | Verified/estimated separated |
| Fix suggestion | What must be fixed server-side | 1–3 sentences |
| Evidence | Raw requests/responses, screenshots (masked) | Attachments |
There’s a reason for the six sections’ order. The triager judges "is it worth a look" from the title and summary, confirms the facts with the reproduction steps, and sets the tier with the impact. The reader’s work order is the document’s section order.
2-2. The Triager’s 5 Minutes
A triager’s day is reviewing dozens of reports. What a report demands, seen from their side, is this — ① they want to know what bug it is from the title alone. ② The reproduction steps must have no omitted premises (not "log in" but "click what, with which account"). ③ Impact must be a scenario, not an exclamation. ④ It helps if the reward-tier grounds connect to the program’s reward table.
Exaggerating impact erodes trust; under-describing it erodes reward. The answer is neither — it’s writing the facts, exactly.
2-3. Responsible Disclosure
Responsible disclosure is the promise the finder of a vulnerability keeps — report only through official channels, give the company time to fix, and don’t publish before a fix or an agreement. It’s written into most programs’ rules, and breaking it can become a legal problem beyond losing the reward. Posting your report on social media is "disclosure," not "reporting."
2-4. Learning from Great Examples — Hacktivity
On HackerOne, resolved reports whose authors consented to disclosure are published (Hacktivity). Reading 3 disclosed reports while analyzing their structure is the fastest learning — what the titles look like, how many steps the reproduction has, what sentences the impact uses. Actually browsing them is your job; this chapter provides a template extracted from that structure.
Analyze as you read, like this. ① Can you guess the vulnerability from the title alone? ② Where does step 1 of the reproduction start — most begin at account creation or environment description. ③ Is the impact sentence a scenario of "an attacker can do X," not "this is scary"? Read 3 pieces checking those three things, and the skeleton of a good report comes into view.
3. Follow Along
3-1. Dissecting a Bad Report
First, see what a rejected report looks like. It’s the same IDOR.
Title: Found a serious security problem
Hello. Your site has a serious vulnerability.
All user information is visible. Fix it quickly.
I found it, so give me a big reward.
How to read it: count the problems — ① the title has no vulnerability info. ② No mention of which feature. ③ No reproduction method. ④ The impact is an exclamation ("all visible"). ⑤ The reward demand is pressure. This report can’t be reproduced, so it comes back N/A.
3-2. A Good Report — The Template
Secure the skeleton first.
# Title: [Impact] is possible in [feature] due to [cause]
### Summary
(2–3 sentences — what, why, how serious)
### Reproduction steps
1. (Starting from account creation — omit no premises)
2. ...
### Impact
- Verified: (facts with evidence)
- Estimated: (extension from structure — always marked separately)
- Reward-tier grounds: (which sentence of the program's reward table it matches)
### Fix suggestion
(1–3 sentences of server-side action)
### Attachments
- Raw request/response (session · personal info masked)
- Screenshots (sensitive info masked)
3-3. Writing for Real — Turning the Lab’s IDOR into a Report
Fill the template with the results measured in Step 317. The reproduction steps are written on lab terms; a real-world report would have real URLs and the account-creation procedure.
# Title: Others' personal information readable via missing ownership verification in the API user lookup (IDOR)
### Summary
The `/api/v1/users/{id}` endpoint checks only whether the caller is logged in
and does not verify that the requester matches the resource's owner. Logging in
with any account and changing the ID exposes another user's email, phone
number, and address.
### Reproduction steps
1. Create 2 test accounts (A, B). (Lab: alice=1001, bob=1002)
2. Log in as A:
POST /api/v1/login {"user": "alice", "pw": "alice-pass!"}
3. With A's session, request B's resource:
GET /api/v1/users/1002
4. The 200 response contains B's personal information (Attachment 1).
### Impact
- Verified: with A's session, read 1 record of account B (id 1002)'s email,
phone number, and address.
- Estimated: since the IDs are sequential numbers (1003 confirmed 404),
exposure likely extends to the full number of accounts. No other real
accounts' data was opened.
- Tier grounds: matches the reward table's "Medium — reading others' data,
e.g., IDOR."
### Fix suggestion
The server must verify the ownership relation between the session user and
the queried id, returning 403 on mismatch. Switching sequential numeric IDs
to unguessable identifiers is a secondary measure (the root fix is
authorization verification).
### Attachments
- Attachment 1: raw request/response — evidence_idor.txt (session · personal info masked)
How to read it: compare with 3-1. The reproduction steps start "from account creation," the impact separates verified/estimated, and the tier grounds connect to a reward-table sentence. A triager can reproduce this report within 5 minutes.
3-4. Self-Review — The Zero-Context Reader Test
Before submitting, re-read the report through the eyes of "someone who knows nothing." Check questions.
- Does reproduction step 1 start from the very beginning, like "create accounts"?
- Is every URL, ID, and account name written concretely?
- Are there no premises you skipped as "obvious" (login state, permissions, environment)?
- Are the verified and the estimated separated in the impact?
- Is the evidence free of raw session cookies and others’ personal info?
How to read it: a single ‘no’ is where the triager gets stuck too. A report that sticks goes back and forth with clarification requests and its verdict gets delayed — smooth reproduction is a fast reward.
3-5. Final Pre-Submission Check
If this were a real submission, you’d pull the operations brief (Step 314) back out here.
□ Is this vulnerability's asset IN scope? (e.g., api.lab.local — IN)
□ Did any test break a prohibited action? (automation limits, DoS, etc.)
□ Did verification happen only between test accounts? (A/B — yes)
□ Did others' data stop at 1 record of proof? (yes — 1002 only)
□ Is the evidence masked? (session · email · address — yes)
How to read it: these five boxes are bug bounty ethics in summary. A technically perfect report with even one ‘no’ here makes the reporter the violator.
4. Missions & Exercises
Mission — Complete One Report
- Using 3-3’s report as your reference, write
report_IDOR.mdfor the vulnerability confirmed in Step 317 — all 6 sections - Review the reproduction steps with 3-4’s five questions, and write the history of what you fixed at the end of the file
- Write reward-tier grounds in the impact box — quote a reward-table sentence from your Step 314 operations brief
- Check all five boxes of 3-5’s final check and write the date
Exercises
Exercise 1. Explain what difference a report titled "Found a serious security problem" versus one in the "[impact] in [feature] due to [cause]" format makes to triage time.
Exercise 2. Explain from the triager’s perspective why the single line "log in" is insufficient in reproduction steps.
Exercise 3. Explain what harm exaggerating impact and under-describing impact each cause.
Exercise 4. Name the three promises of responsible disclosure, and explain why posting a report on social media first is a problem.
Answers & completion criteria · expand/collapse
5. Model Answers & Completion Criteria
Mission Model Answer
Example review history:
[Self-review history]
- Reproduction steps started at "log in" → added the account-creation step (step 1)
- Impact described "all users exposed" as fact → separated into verified/estimated
- Evidence contained the raw session cookie → replaced with <session value masked>
How to verify: ① are all 6 sections present? ② do the reproduction steps start from account creation? ③ are verified/estimated separated? ④ is there a quoted reward-table sentence? ⑤ are the final check’s 5 boxes checked? All ‘yes’ means complete.
Exercise Answers
Answer 1. A triager sets priorities and review order from titles. An info-free title requires opening the file and then re-figuring out what bug it is, while a [feature][cause][impact] title lets them anticipate scope and severity before review. The same vulnerability gets judged faster when it’s quick to grasp.
Answer 2. "Log in" lacks which account, via which path, in which permission state. The triager doesn’t know the reporter’s environment, so they must fill these blanks with guesses — and a wrong guess fails the reproduction and sends it back as "cannot reproduce." Reproduction steps must fix even environmental premises into sentences — like "log in as test account A (see step 1 for account creation)."
Answer 3. With exaggeration, the moment the reproducing triager confirms "it doesn’t go that far," the whole report’s trust erodes, and everything that reporter claims afterward gets discounted. Under-description gets judged at a lower tier than reality and the reward shrinks. Both harms return to the reporter, so honest description with verified facts separated from estimates is best.
Answer 4. The promises of responsible disclosure are ① report only through official channels, ② give the company time to fix, ③ don’t publish before a fix or agreement. Posting on social media first breaks all three — and above all, it hands information about a not-yet-fixed vulnerability to real attackers. The reason for the promise: user protection comes before the glory of discovery.
Completion Criteria Checklist
- [ ] I can state the standard 6-section report structure in order
- [ ] I can point out at least 5 problems of a bad report
- [ ] I completed
report_IDOR.mdwith all 6 sections filled - [ ] I reviewed the reproduction steps with the 5 "zero-context reader" questions
- [ ] I wrote verified/estimated separation and reward-tier grounds in the impact
- [ ] I passed the final check’s 5 boxes (scope · rules · test accounts · 1-record proof · masking)
6. Common Pitfalls & Fixes
Wall 1. Omitting "obvious things" while writing reproduction steps
Symptom: it works in my head, but "cannot reproduce" comes back from the triager.
Cause: the author knows the context, so they don’t notice their own omissions.
Fix: review with 3-4’s five questions. Especially check whether the reproduction steps start "from account creation." Setting it aside for a day and reading it tomorrow also works — tomorrow’s you is the zero-context reader.
Wall 2. Not knowing how far to write the impact
Symptom: you hesitate over whether to go as far as "all users at risk."
Cause: the boundary between verified and estimated is blurry.
Fix: write them split, like "verified: can read 1 of others’ posts / estimated: likely applies to all users (sequential ID structure)." Triagers trust the honest split, and the estimated box becomes grounds for a tier upgrade.
Wall 3. The fix suggestion is "please improve security"
Symptom: the fix-suggestion box is abstract.
Cause: you wrote only a conclusion with no cause analysis.
Fix: write cause → action. A sentence the server-side developer can move straight into a ticket — "no ownership verification → compare the session user with the resource id and return 403 on mismatch" — is a good suggestion.
Wall 4. Writing about money in the report
Symptom: you put "please give me a big reward" in the report.
Cause: the reward is decided not by the report but by the verdict and the reward table.
Fix: all a report can do is present tier grounds — "this matches the reward table’s ‘Medium — reading others’ data.’" Demanding amounts only erodes trust.
Wall 5. Delaying submission for fear of rejection
Symptom: you polish the report for days.
Cause: perfectionism — but meanwhile, if someone reports first, you’re a duplicate.
Fix: once you’ve passed 3-5’s five boxes, submit. Reporting is also a first-come game. Whatever is lacking can be supplemented as you answer the triager’s questions — that back-and-forth is Step 319’s topic.
7. Summary
Today’s Concepts
| Concept | One-line explanation |
|---|---|
| Report’s 6 sections | Title · summary · reproduction steps · impact · fix suggestion · evidence |
| The triager’s 5 minutes | A context-free reviewer must be able to reproduce immediately |
| Impact description | Verified/estimated separated + connected to a reward-table sentence — both exaggeration and understatement cost you |
| Fix suggestion | Cause → server-side action, a sentence a developer can move straight into a ticket |
| Responsible disclosure | Official channel · time to fix · no publication before agreement |
| Hacktivity | A collection of disclosed accepted reports — the best textbook for structure |
Today’s Commands & Formats
| Tool | What it does |
|---|---|
| Title = [feature][cause][impact] | Conveys the whole vulnerability in one sentence |
| Reproduction steps = numbered from account creation | Practicing the no-omitted-premises rule |
| "Verified / Estimated" marking | Separating fact from extension |
| 3-5 final check’s 5 boxes | Scope · rules · test accounts · 1-record proof · masking |
The Core Instinct
The skill of finding vulnerabilities and the skill of getting rewarded for them are different — the latter is "writing." The same finding lands in a different tier over one title line, one reproduction-step premise, one verified/estimated split. The reports in 3-1 and 3-3 describe the same bug, but one is N/A and one is Medium. You are now both someone who finds and someone whose findings get accepted. What remains is the actual submission and the conversation with the triager — that final step comes next.
Once every box is checked, Step 318 is complete.
ONE STEP FURTHER
Finished this lesson?
Check the completion criteria, then mark your progress.