Skip to content
← Ethical Hacking · intermediate · 10 min · 15 / 31

Pentest Reporting

Professional report structure, CVSS scoring, evidence documentation, executive summaries, and remediation guidance.

pentest reportreportingCVSSexecutive summaryremediationdocumentationbug bounty

Real-World Analogy

A doctor who finds a tumor but writes an illegible report helps no one. The penetration test exists to improve security — the report is the deliverable. A clear report that drives remediation is more valuable than a sophisticated attack that produces nothing actionable.

Why Reporting Is the Hard Part

Most pentest training focuses on attack techniques. Most penetration testers fail at reporting. A report that:

  • Contains findings without evidence = dismissed as false positive
  • Has technical depth but no executive summary = not read by decision-makers
  • Lists vulnerabilities without remediation = client doesn’t know what to do
  • Uses unexplained jargon = misunderstood, misimplemented

The measure of a pentest is whether security improved. That requires a good report.

Report Structure

1. Cover Page
   - Engagement title
   - Client name
   - Testing dates
   - Report date
   - Classification (Confidential)
   - Assessment team

2. Executive Summary (1-2 pages)
   - Non-technical audience: C-suite, board
   - What was tested, what was found, overall risk posture
   - Top 3-5 critical findings
   - Risk rating (Critical/High/Medium/Low/Info counts)
   - Key recommendations in plain English

3. Scope and Methodology
   - What was in scope (IP ranges, domains, URLs)
   - What was out of scope
   - Testing methodology used (PTES, OWASP, OSSTMM)
   - Testing dates and restrictions

4. Findings (bulk of the report)
   - One section per finding
   - Ordered by severity (Critical first)

5. Appendices
   - Detailed scan output
   - Tool commands and full evidence
   - Successful credentials list
   - Complete URL lists tested

Finding Documentation Template

Each finding follows this structure:

## FIND-001: SQL Injection in User Search Endpoint

**Severity:** Critical
**CVSS v3.1 Score:** 9.8 (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)
**Affected Component:** https://app.example.com/api/users/search
**CWE:** CWE-89 (SQL Injection)

### Description

The user search endpoint (`/api/users/search?q=`) is vulnerable to SQL injection.
The `q` parameter is directly concatenated into a SQL query without sanitization
or parameterization, allowing an attacker to modify the query structure.

### Impact

An unauthenticated attacker can:
1. Extract all records from the database, including user credentials and PII
2. Modify or delete database records
3. Potentially execute operating system commands if the database user has
   elevated privileges (tested: `xp_cmdshell` was not available)

During testing, we extracted 15,847 user records including email addresses,
bcrypt password hashes, and home addresses. We did not exfiltrate or retain this data.

### Evidence

**Request:**

GET /api/users/search?q=admin’+OR+‘1’=‘1 HTTP/1.1 Host: app.example.com Authorization: Bearer [redacted]


**Response (truncated):**
```json
{
  "users": [
    {"id": 1, "email": "admin@example.com", "role": "superadmin"},
    {"id": 2, "email": "alice@example.com", "role": "user"},
    ... (15,845 additional records)
  ],
  "total": 15847
}

Screenshot: [SCREENSHOT-001.png]

SQLmap output confirming injection:

[14:23:11] [INFO] GET parameter 'q' is 'Generic UNION query (NULL) - 1 to 20 columns' injectable
[14:23:11] [INFO] the back-end DBMS is MySQL

Remediation

Immediate (within 24 hours):

  • Disable the /api/users/search endpoint until patched

Short-term (within 1 week):

  • Replace string concatenation with parameterized queries:
// Vulnerable (current code):
const query = `SELECT * FROM users WHERE name LIKE '%${userInput}%'`;

// Fixed (parameterized query):
const query = 'SELECT * FROM users WHERE name LIKE ?';
const results = await db.query(query, [`%${userInput}%`]);

Long-term:

  • Implement a Web Application Firewall with SQL injection rules
  • Add database activity monitoring to alert on bulk data access
  • Conduct SQL injection training for the development team
  • Add automated SAST scanning to the CI pipeline (Semgrep, Checkmarx)

References


## Executive Summary Template

```markdown
## Executive Summary

### Engagement Overview

[Consulting firm] conducted a penetration test of [Company]'s web application and
supporting infrastructure from [start date] to [end date]. The assessment was
authorized under the scope of work signed on [date].

### Overall Risk Posture

The assessment identified **27 vulnerabilities**, including **3 Critical** and
**6 High severity** issues. A critical SQL injection vulnerability allows
unauthenticated access to the entire customer database (15,847 records). Additionally,
two separate pathways to complete administrative compromise were identified.

| Severity | Count |
|----------|-------|
| Critical | 3     |
| High     | 6     |
| Medium   | 11    |
| Low      | 7     |

### Key Findings

1. **SQL Injection (Critical)** — Unauthenticated attackers can extract all customer
   data. Patch within 24 hours. (FIND-001)

2. **Default Credentials on Admin Panel (Critical)** — The admin dashboard is accessible
   with credentials "admin/admin". Change immediately. (FIND-003)

3. **Unpatched Server (High)** — The web server runs Apache 2.4.29, which has
   multiple known vulnerabilities. Update to 2.4.57. (FIND-008)

### Recommendations

Immediate actions (within 24 hours):
- Disable the user search API endpoint
- Change admin dashboard credentials
- Apply emergency WAF rules for SQL injection patterns

Short-term (within 30 days):
- Implement parameterized queries across all database interactions
- Patch Apache to the latest stable version
- Enable multi-factor authentication for all admin accounts

Long-term (within 90 days):
- Establish a vulnerability management program
- Integrate security testing into the development pipeline
- Conduct developer security training

CVSS Scoring in Practice

Scoring matrix for common finding types:

SQL Injection (unauthenticated, full DB read):
  AV:N  AC:L  PR:N  UI:N  S:U  C:H  I:H  A:H = 9.8 (Critical)

Stored XSS (affects all users):
  AV:N  AC:L  PR:L  UI:R  S:C  C:H  I:L  A:N = 8.0 (High)

IDOR (access another user's data):
  AV:N  AC:L  PR:L  UI:N  S:U  C:H  I:N  A:N = 6.5 (Medium)

Information Disclosure (server version in header):
  AV:N  AC:L  PR:N  UI:N  S:U  C:L  I:N  A:N = 5.3 (Medium)

Missing security header (X-Frame-Options):
  AV:N  AC:H  PR:N  UI:R  S:U  C:L  I:L  A:N = 4.2 (Medium)

Use first.org/cvss/calculator/3.1 — don’t calculate manually.

Evidence Collection During Testing

# Screenshot every finding as you find it — don't wait to the end
# Naming: FIND-001-sql-injection-request.png
# Tools: flameshot (Linux), Greenshot (Windows)

# Save all HTTP requests/responses
# Burp Suite: right-click → Save Item → save as .txt

# Export Burp project at end of engagement
# Burp Suite Pro → Project → Save a copy

# Nmap output
sudo nmap -sV -sC -oA scan-results 192.168.1.100

# Keep all tool output
nikto -h http://target.com 2>&1 | tee nikto-output.txt
sqlmap -u "..." --dump 2>&1 | tee sqlmap-output.txt

# Terminal session recording
script -a pentest-session.log   # records everything typed and output

Bug Bounty Reporting

Bug bounty reports are shorter but follow the same structure:

## Title: SQL Injection in /api/search Allows Database Dump

**Severity:** Critical
**CVSS:** 9.8
**Asset:** api.target.com

## Summary
The `q` parameter in the search API is injectable, allowing full database extraction
without authentication.

## Steps to Reproduce
1. Send the following request:
   `GET /api/search?q=' OR 1=1-- HTTP/1.1`
2. Observe all records returned instead of empty results
3. Use the UNION technique to extract tables:
   `GET /api/search?q=' UNION SELECT table_name,NULL FROM information_schema.tables--`

## Impact
Complete database read access including user PII and credentials.

## Proof of Concept
[Screenshot showing database contents returned]

## Suggested Fix
Use parameterized queries:
```sql
SELECT * FROM products WHERE name LIKE ?

Pass %${userInput}% as the bound parameter.

References

  • OWASP SQL Injection Prevention Cheat Sheet

**Bug bounty tips:**
- Clear title with the vulnerability type and affected endpoint
- Steps must be reproducible exactly — triagers follow them verbatim
- Include proof (screenshot, video, response body) — not just "I saw it"
- Impact section should explain real-world consequences, not just technical effect
- Suggest a fix — shows competence and reduces back-and-forth

## Certifications Roadmap

Entry level: CompTIA Security+ → security fundamentals, required for many jobs CompTIA Network+ → networking (do before Security+ if new to networking) eJPT (eLearnSecurity) → hands-on entry pentest, beginner-friendly

Intermediate: OSCP (Offensive Security) → gold standard practical cert, required by most pentest firms CEH (EC-Council) → vendor cert, less respected but widely recognized by HR eWPT (eLearnSecurity) → web application penetration testing

Advanced: OSED (Exploit Developer) → advanced Windows exploitation (by OffSec) OSEP (Experienced Pentester) → evasion, AD attacks CRTP (Certified Red Team Pro) → Active Directory attacks CISSP → management/governance track

Path recommendation:

  1. Security+ (foundational, opens doors)
  2. TryHackMe + HackTheBox for hands-on
  3. OSCP (requires: at least 3 months of HTB/VulnHub practice)
  4. Specialize: OSED (binary), OSEP (AD), or web-focused certs