Finding a critical vulnerability is only half the battle in modern bug bounty hunting. The other half—the half that dictates whether you get paid top-tier bounties in hours or spend three weeks arguing in comments—is how you write the report.
Triagers on platforms like HackerOne, Bugcrowd, and Intigriti, as well as internal Product Security (ProdSec) teams at tech giants, review dozens of submissions every hour. They face triage fatigue, aggressive Service Level Agreements (SLAs), and mountains of spam from automated scanner dumps.
When your submission arrives with cryptic one-line notes, noisy Burp Suite exports, or inflated severity scores, triagers are forced to spend mental bandwidth reverse-engineering your intent. The result is predictable: delayed reproduction, requests for clarification, disputed severities, or worse, outright closure as Informative or Cannot Reproduce.
Conversely, an airtight, professional report removes every ounce of friction. The triager verifies the bug in 90 seconds, selects the CVSS vector you calculated, and escalates it to the engineering team with payment approval on the same day.
Here is the offensive researcher’s blueprint for structuring high-impact reports, calculating mathematically sound CVSS scores, engineering deterministic Proofs of Concept (PoCs), and mastering triage queue dynamics.
1. The Anatomy of an Airtight Report Structure
A winning report follows a journalistic principle: Bottom Line Up Front (BLUF). A triager should understand the vulnerability class, target surface, and business exposure within 20 seconds of opening your ticket.
+-------------------------------------------------------------------------+
| THE 5-TIER REPORT ARCHITECTURE |
+-------------------------------------------------------------------------+
| 1. Executive Summary (BLUF) -> Target, Vuln Type, Impact in 30 sec |
| 2. Environment & Prerequisites-> Roles, Auth states, Target URLs |
| 3. Step-by-Step Reproduction -> Discrete, deterministic, numbered steps|
| 4. Clean Proof of Concept -> Minimal cURL / Python / Short video |
| 5. Impact & Remediation -> Concrete blast radius + Fix guidance |
+-------------------------------------------------------------------------+
1. The Executive Summary (BLUF)
Never bury the lead. Start with a succinct 3-to-4 sentence briefing that defines:
- Target Asset: Exact domain, API route, or mobile bundle.
- Vulnerability Type: CWE name (e.g., CWE-639: Authorization Bypass Through User-Controlled Key).
- Core Impact: What unauthorized action an attacker can execute.
- Preconditions: Whether the attack requires an authenticated account, elevated privileges, or user interaction.
Weak Summary:
“I found an IDOR in the billing section. You can see other people’s invoices. Please fix ASAP and award bounty.”
High-Impact Summary:
“An Insecure Direct Object Reference (IDOR / BOLA) in theGET /api/v2/organizations/{org_id}/invoicesendpoint enables an authenticated attacker belonging to Organization A to exfiltrate proprietary billing records, line-item pricing, and customer PII belonging to any arbitrary organization by incrementing the numericorg_idpath parameter. No user interaction or elevated administrative permissions are required.”
2. Environment & Prerequisites
Triagers often test against staging, sandboxed multi-tenant environments, or dedicated testing accounts. Disclose your setup parameters immediately:
| Variable | Recommended Specification | Example |
|---|---|---|
| Base URL | Exact origin tested | https://app.target-enterprise.com |
| User A (Attacker) | Role, account ID, test email | Role: Member, ID: usr_912a, attacker@pentest.local |
| User B (Victim) | Role, tenant ID, target email | Role: Org Admin, Tenant: org_481b, victim@pentest.local |
| HTTP Client / Platform | Runtime, browser, or CLI tool | Firefox 129 / Burp Suite v2026.8 / Python 3.12 |
| Feature Flags / Settings | Prerequisite configurations | Multi-currency billing must be enabled in Org Settings |
3. Step-by-Step Reproduction Steps
Your reproduction section is an executable recipe. If a step fails, the report stalls.
- Start from zero: Never assume the target account already has the necessary resources populated. Include the prerequisite object creation step.
- Use numbered, discrete steps: Avoid paragraphs. Every user interaction or HTTP request should be a single numbered bullet.
- Differentiate actors explicitly: Clearly label when an action is taken by Attacker (User A) versus Victim (User B).
### Steps to Reproduce
1. Log in to Account B (Victim) at `https://app.target.com/login`.
2. Navigate to `Settings -> Billing -> Invoices` and note the generated invoice ID (e.g., `inv_99812`).
3. Log out of Account B, and log in to Account A (Attacker) in an incognito browser session.
4. Verify that Account A has no access to Account B's invoices in the dashboard UI.
5. Send the following cURL request using Account A's Bearer token, replacing `{INVOICE_ID}` with `inv_99812`:
[cURL Command]
6. Observe that the server returns HTTP/2 200 OK with Account B's full invoice data, including customer tax IDs and billing addresses.
2. Impact Calculation: Turning Findings into Top Payouts
The single greatest point of friction between security researchers and triage teams is Impact. Researchers often argue theoretical worst-case scenarios, while triage teams are bound by demonstrable business risk.
[ THEORETICAL SPECULATION ] [ DEMONSTRABLE RISK ]
"If an attacker chains this with an 0-day "An unauthenticated remote attacker
in Chrome, they could pivot into the AWS can read 4.2M unencrypted customer
root account and delete production." credit records via a single looped API call."
| |
v v
[ Lowered to Low / N/A ] [ Validated as CRITICAL ]
The Golden Formula of Business Impact
To justify a High or Critical rating, translate technical exploitation into tangible business consequences:
- Confidentiality Blast Radius: Exactly what sensitive data is exposed? Is it public marketing data, internal metadata, customer PII (GDPR/CCPA impact), or secret credentials (API keys, AWS tokens)?
- Integrity Blast Radius: Can the attacker tamper with state? Can they alter financial balances, modify user permissions, or plant malicious backdoors?
- Availability Blast Radius: Does exploitation exhaust database pools, delete tenant partitions, or take down core authentication services?
- Volume & Automation: Can this attack be scripted across the entire user base (e.g., brute-forcing sequential 32-bit IDs) without rate limits?
CVSS v3.1 Matrix Breakdown for Bug Hunters
Do not guess CVSS scores. Calculate each metric accurately and provide the full CVSS vector string in your submission:
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N (Base Score: 8.1 - HIGH)
| Metric | Code | Hacker’s Best Practice |
|---|---|---|
| Attack Vector (AV) | AV:N |
Almost all web bugs are Network (AV:N). Do not claim AV:N if physical device access is required. |
| Attack Complexity (AC) | AC:L vs AC:H |
Is execution deterministic (AC:L), or does it depend on winning an unpredictable race window or man-in-the-middle positioning (AC:H)? |
| Privileges Required (PR) | PR:N / PR:L / PR:H |
PR:N: Unauthenticated. PR:L: Standard user. PR:H: Workspace Administrator. |
| User Interaction (UI) | UI:N vs UI:R |
Does the exploit run autonomously (UI:N), or must the victim click a crafted link / accept a prompt (UI:R)? |
| Scope (S) | S:U vs S:C |
Did the vulnerability cross security boundaries (e.g., escaping a sandboxed iframe to host origin, or SSRF pivoting to AWS IMDSv1)? |
| Confidentiality (C) | C:H / C:L / C:N |
C:H: Complete database or full PII exfiltration. C:L: Partial non-sensitive info disclosure. |
The CVSS Inflation Trap
One of the quickest ways to lose credibility with a triage team is CVSS Inflation:
- Filing a Self-XSS (which requires copying code into Developer Tools) as
CVSS 9.8 Critical. - Filing a Rate Limiting missing on contact form as
CVSS 7.5 High Denial of Service. - Filing an IDOR leaking public user profiles as
CVSS 8.6 High PII Exfiltration.
When you submit an inflated score, triagers are forced to downvote it, which immediately creates an adversarial dynamic. When you accurately submit an 8.1 and thoroughly defend it with empirical evidence, triagers respect your judgment and advocate for your payout with the program manager.
3. Proof of Concept (PoC) Engineering
The best PoCs are clean, minimal, non-destructive, and copy-pasteable. If a triager has to install four unknown npm packages or compile an unverified binary, your report will sit in the queue.
1. The Clean cURL Standard
Never copy raw HTTP requests directly from Burp Suite without stripping noise. Remove client-specific headers like sec-ch-ua, User-Agent, Accept-Language, Sec-Fetch-*, and browser analytics cookies.
# Clean, deterministic PoC cURL Command
curl -i -sS -X POST "https://api.target.com/v2/organization/billing/transfer" \
-H "Host: api.target.com" \
-H "Authorization: Bearer <ATTACKER_TOKEN>" \
-H "Content-Type: application/json" \
--data '{"victim_tenant_id":"org_88192","destination_account":"attacker_vault"}'
Key flags for reproducible cURL commands:
-i: Includes HTTP response headers (proves status code and cookies returned).-sS: Silent mode, but shows errors if the network connection drops.--path-as-is: Crucial when demonstrating path traversal or URL normalization bypasses (prevents curl from resolving../locally).
2. Standalone Python Reproduction Script
For complex exploits (such as race conditions, cryptographic flaws, or multi-step token exchanges), provide a self-contained Python script utilizing only Python’s standard library or requests.
#!/usr/bin/env python3
"""
Target: https://api.target.com
Vulnerability: Insecure Direct Object Reference in Invoice Export
Author: Shawn R. (Packets & Profits)
Usage: python3 poc_idor.py <ATTACKER_BEARER_TOKEN> <VICTIM_ORG_ID>
"""
import sys
import json
import urllib.request
import urllib.error
def verify_idor(attacker_token: str, victim_org_id: str):
url = f"https://api.target.com/v2/organizations/{victim_org_id}/invoices"
headers = {
"Authorization": f"Bearer {attacker_token}",
"Accept": "application/json",
"User-Agent": "Security-Research-PoC"
}
req = urllib.request.Request(url, headers=headers, method="GET")
try:
with urllib.request.urlopen(req) as resp:
status = resp.status
body = resp.read().decode("utf-8")
data = json.loads(body)
print(f"[+] HTTP Status: {status}")
print(f"[!] IDOR CONFIRMED: Successfully accessed victim tenant data!")
print(f"[*] Records retrieved: {len(data.get('invoices', []))}")
print(f"[*] First invoice leaked: {data['invoices'][0]['invoice_id']} | Amount: ${data['invoices'][0]['total']}")
sys.exit(0)
except urllib.error.HTTPError as e:
print(f"[-] Access denied or failed: HTTP {e.code}")
sys.exit(1)
if __name__ == "__main__":
if len(sys.argv) < 3:
print(f"Usage: {sys.argv[0]} <ATTACKER_TOKEN> <VICTIM_ORG_ID>")
sys.exit(1)
verify_idor(sys.argv[1], sys.argv[2])
3. Screen Recordings vs. Screenshots: The Decision Matrix
| Vulnerability Category | Best PoC Media | Rationale |
|---|---|---|
| IDOR / BOLA / SSRF | Raw HTTP Request + Response | Text is searchable, diffable, and immediate. Videos waste triager time. |
| Stored XSS / CSRF | Screenshot of Alert Box + Payload | A single screenshot showing document.domain in the modal proves execution. |
| Race Conditions / Limit Bypass | Video (under 60s) or Turbo Intruder Log | Proves concurrency and simultaneous multi-request acceptance. |
| Multi-Step Account Takeover | Screen Recording (MP4, 720p/1080p) | Shows both attacker and victim browsers side-by-side in real time. |
Screen Recording Etiquette:
- Keep it under 90 seconds.
- Do not include background music or prolonged typing.
- Use dual browser windows (one colored red for Attacker, one blue for Victim) so the triager can follow session state transitions instantly.
4. What Actually Gets You Paid & Triaged Faster
Triage teams operate under operational pressure. When you align your workflow with their internal success metrics, your reports fly through validation.
RESEARCHER SUBMITS REPORT
│
▼
┌──────────────────────────────────────┐
│ TRIAGER FIRST LOOK (<2 min) │
│ - Is target in scope? │
│ - Is vulnerability class eligible? │
│ - Are steps clear & reproducible? │
└──────────────────┬───────────────────┘
│
Passes Quick Filter?
┌──────────┴──────────┐
▼ ▼
[ YES ] [ NO ]
Reproduce in sandbox Request more info /
Confirm impact Flag as Informative /
Escalate to Client Queue delays 5-10 days
│
▼
Bounty Paid Fast ($$$)
The 5 Sins That Stall Reports
- The “Check out my video” trap: Submitting a blank report body with only a YouTube or Google Drive link. Many enterprise clients prohibit triagers from clicking unverified third-party external video links. Always include the full written reproduction in the report body.
- Testing in single-tenant isolation: Proving you can modify your own user profile does not prove an IDOR. You must demonstrate crossing an authorization boundary between two distinct test accounts you control.
- Leaving active attack artifacts: Fuzzing with
test<script>alert(1)</script>on production forms and abandoning 500 polluted records in the company’s live system. Clean up your artifacts or use non-destructive payloads like"><b/onmouseover=console.log(1)>. - Emotional dispute escalation: When a triager asks a clarifying question or challenges the severity, responding with personal attacks or threats to public-disclose guarantees your report gets locked.
- Noisy Burp project state dumps: Uploading a 200MB
.burpfile instead of isolating the single offending HTTP exchange.
Constructive Dispute Resolution Protocol
If a triager marks your report as Informative or downgrades the severity unfairly:
- Do not argue semantics: Do not say “You don’t understand security, this is clearly Critical!”
- Reference Program Policy & RFCs: Cite the specific scope rules:
“According to the program brief under ‘Eligible Vulnerabilities’, Section 3 explicitly includes Broken Object Level Authorization on/api/v2/*. Here is the exact boundary crossover demonstrated…” - Provide a concrete attack chain: If they claim the leaked token has no impact, show where that token can be replayed to modify user email or billing state.
- Request Platform Mediation calmly: If at an impasse on HackerOne or Bugcrowd, politely request platform mediation:
“I respect the triage assessment; however, because this endpoint allows unrestricted exfiltration of customer PII across tenant boundaries, could we please request a platform mediator or program manager review for second-tier evaluation?”
Propose the Remediation (The ProdSec Delight)
Security engineers who review triaged tickets have to write the fix. When you supply the remediation logic in code, you cut their engineering cycle in half. Many programs award discretionary bonus bounties (+$250 to +$1,000) for clean fix proposals.
### Suggested Remediation
In `app/controllers/invoices_controller.py`, enforce an explicit ownership check using the authenticated session's tenant context rather than trusting the user-supplied `org_id`:
```python
# Vulnerable
invoice = Invoice.objects.filter(id=invoice_id, org_id=request_org_id).first()
# Secure
current_org = request.user.organization
invoice = Invoice.objects.filter(id=invoice_id, organization=current_org).first()
if not invoice:
raise Http404("Invoice not found or access denied.")
---
## 5. The Battle-Tested Bug Bounty Report Template
Use this markdown template for your future submissions on HackerOne, Bugcrowd, Intigriti, or direct private disclosure programs.
```markdown
# [Vulnerability Type] in [Endpoint/Component] leads to [Business Impact]
## Summary
A [Vulnerability Class, e.g., Broken Object Level Authorization] vulnerability exists in the [Target Endpoint/Feature]. An authenticated attacker with [Attacker Privilege Level] can [Specific Exploitation Action], leading to [Direct Impact, e.g., unauthorized access to full customer financial records].
- **Vulnerable URL**: `https://api.target.com/v1/resource/{id}`
- **HTTP Method**: `GET` / `POST` / `PUT` / `DELETE`
- **CVSS v3.1 Score**: `8.5 (High)` - `CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N`
- **CWE**: `CWE-639: Authorization Bypass Through User-Controlled Key`
---
## Testing Environment & Credentials
- **Target URL**: `https://app.target.com`
- **Attacker Account (User A)**: `attacker_test@pentest.com` (Org ID: `org_111`)
- **Victim Account (User B)**: `victim_test@pentest.com` (Org ID: `org_222`, Resource ID: `doc_999`)
---
## Steps to Reproduce
1. Log in to User B (Victim) account and navigate to `https://app.target.com/documents`.
2. Locate document `doc_999` and note that it contains sensitive personal data.
3. Open an Incognito window, log in as User A (Attacker).
4. Send the following cURL request using User A's authorization token, attempting to access User B's document:
```bash
curl -i -sS -X GET "https://api.target.com/v1/documents/doc_999" \
-H "Host: api.target.com" \
-H "Authorization: Bearer <USER_A_TOKEN>" \
-H "Accept: application/json"
- Observe the response: The server responds with
HTTP/2 200 OKand returns the complete document metadata and download URI belonging to User B.
Proof of Concept
Raw HTTP Request
GET /v1/documents/doc_999 HTTP/2
Host: api.target.com
Authorization: Bearer eyJhbGciOi...[User A Token]
Accept: application/json
Raw HTTP Response
HTTP/2 200 OK
Content-Type: application/json
Date: Wed, 02 Sep 2026 23:40:00 GMT
{
"document_id": "doc_999",
"owner_org_id": "org_222",
"title": "Quarterly Financial Audit & PII Records",
"file_url": "https://s3.us-east-1.amazonaws.com/target-vault/doc_999.pdf"
}
Business Impact
An attacker can enumerate sequential document IDs to exfiltrate private internal documents across all tenants in the multi-tenant architecture. This breaks multi-tenant isolation, exposing customer data in violation of GDPR and SOC2 compliance standards.
Suggested Remediation
Implement tenant-scoped database queries ensuring that requests for documents validate document.organization_id == current_user.organization_id before returning records.
---
## 6. Pre-Submission Checklist
Before hitting the **Submit Report** button, run through this 60-second flight check:
- [ ] **Scope Checked**: Have you verified that the domain/wildcard is explicitly in scope in the program brief?
- [ ] **Zero-State Test**: Can a third party follow your steps without requiring unmentioned prior configuration?
- [ ] **Dual-Account Proof**: Did you prove cross-tenant impact between two separate accounts rather than testing against yourself?
- [ ] **Noise Stripped**: Did you remove useless tracking cookies and user-agent noise from your cURL requests?
- [ ] **Accurate CVSS**: Is your CVSS score justifiable without theoretical speculation?
- [ ] **Clean Artifacts**: Did you sanitize or delete any temporary test data you created during testing?
- [ ] **Professional Tone**: Is the report phrased constructively, focusing on technical vulnerability and remediation?
By engineering your reports with the same precision you apply to exploiting targets, you transform your bug bounty workflow from a frustrating back-and-forth into a predictable, high-payout machine.
