PwnReport is a lightweight command-line tool for turning penetration testing results into a consistent, client-readable security assessment report.
It is designed for security consultants, penetration testers, and developers who already have assessment notes or findings and need a simple way to format, validate, and publish them. PwnReport keeps the source data structured in JSON and produces an offline HTML report with a professional dark theme.
PwnReport is a reporting tool, not a vulnerability scanner. It does not scan targets, exploit vulnerabilities, collect credentials, or replace tools such as Nmap, Burp Suite, Nessus, Nuclei, or Metasploit. Those tools can remain in the assessment workflow while PwnReport becomes the final reporting layer.
The original v0.1 foundation remains intentionally small:
init workspace -> edit report.json -> build report.html
It uses only the Python standard library and generates a self-contained HTML report that can be opened offline. The generated HTML includes a print stylesheet, so it can also be saved as PDF from a browser without adding a PDF library to the project.
PwnReport provides a small, predictable reporting pipeline:
- Create a report workspace with
pwnreport init. - Store engagement information in
report.json. - Add and inspect findings through the CLI or edit the JSON directly.
- Validate required fields, severity values, and unique finding IDs.
- Sort findings by severity.
- Build a self-contained HTML report with:
- Cover page
- Engagement information
- Assessment scope
- Executive summary
- Finding severity summary
- Finding descriptions, impact, evidence, and remediation
This approach is useful when the priority is a stable report format rather than a large platform. The JSON file remains easy to review in Git, generate from another script, or use as the input for future importers.
The v0.2 release does not include scanner importers, a web interface, a database, authentication, CVSS calculation, or native PDF generation. These are intentionally deferred until the core JSON-to-HTML workflow is stable.
- Python 3.9 or newer
- No runtime dependencies
From the repository root:
python3 -m venv .venv
. .venv/bin/activate
python -m pip install -e .
pwnreport init demo-report
pwnreport finding add demo-report/report.json
pwnreport validate demo-report/report.json
pwnreport build demo-report/report.jsonOpen demo-report/output/report.html in a browser. The generated report also
includes a print stylesheet, so the browser's print dialog can be used to save
it as PDF without a PDF dependency.
Without installing the package, use the module directly:
PYTHONPATH=src python3 -m pwnreport --help
PYTHONPATH=src python3 -m pwnreport init demo-report
PYTHONPATH=src python3 -m pwnreport finding add demo-report/report.json
PYTHONPATH=src python3 -m pwnreport validate demo-report/report.json
PYTHONPATH=src python3 -m pwnreport build demo-report/report.jsonpwnreport --version
pwnreport init <directory>
pwnreport validate <report.json>
pwnreport finding add <report.json>
pwnreport finding list <report.json>
pwnreport finding show <report.json> <finding-id>
pwnreport build <report.json>
pwnreport build <report.json> --output <report.html>init creates:
<directory>/
├── report.json
└── output/
The command never overwrites an existing report.json.
Run finding add without field flags to use the interactive prompts:
pwnreport finding add demo-report/report.jsonFor scripts and repeatable automation, provide all fields as flags:
pwnreport finding add demo-report/report.json \
--title "Missing Content Security Policy" \
--severity high \
--affected-asset "https://app.example.com" \
--description "The application does not return a CSP header." \
--impact "Client-side injection can have a wider impact." \
--evidence "Content-Security-Policy was absent from the response." \
--remediation "Deploy a restrictive Content Security Policy."PwnReport assigns IDs automatically in FIND-001 format. It derives the next
ID from the highest existing numeric finding ID rather than reusing deleted
numbers.
Inspect and validate findings before building the report:
pwnreport finding list demo-report/report.json
pwnreport finding show demo-report/report.json FIND-001
pwnreport validate demo-report/report.jsonFinding changes are validated before saving. PwnReport writes a temporary file
beside report.json, flushes it to disk, and atomically replaces the original.
Unknown JSON fields are preserved, so adding a finding does not discard custom
metadata maintained by another tool.
The initial template is intentionally small:
{
"project": {
"name": "Web Application Penetration Test",
"client": "ACME Corporation",
"assessment_type": "Web Application",
"classification": "CONFIDENTIAL",
"author": "Rizko Febri Rachmayadi"
},
"scope": [
"https://app.example.com"
],
"executive_summary": "The assessment identified one high-risk vulnerability.",
"findings": [
{
"id": "FIND-001",
"title": "SQL Injection in Login Endpoint",
"severity": "high",
"affected_asset": "https://app.example.com/login",
"description": "The login endpoint does not safely handle user input.",
"impact": "An attacker may access or modify sensitive application data.",
"evidence": "A crafted input changed the authentication response.",
"remediation": "Use parameterized queries for all database operations."
}
]
}Allowed severity values, in report order:
critical, high, medium, low, info
All project fields and all finding fields are required. Finding IDs must be unique, and invalid input stops the build with a readable validation error.
The roadmap is intentionally incremental. Each stage should preserve the simple JSON-first workflow and remain useful on its own.
Delivered foundation:
- Minimal report schema
-
initandbuildCLI commands - Required-field and severity validation
- Duplicate finding ID detection
- Severity-based finding ordering
- Self-contained dark-theme HTML output
- Browser print stylesheet for optional PDF export
- Standard-library test suite
Current release:
Make authoring reports easier without introducing a database:
-
pwnreport finding add -
pwnreport finding list -
pwnreport finding show <id> -
pwnreport validate <report.json> - Automatic finding ID generation
- Safer editing while preserving the JSON schema
Extend the schema for findings that need more technical context:
- Reproduction steps
- Evidence file references and screenshots
- CWE, CVE, and OWASP mappings
- CVSS vector and score fields
- Methodology and limitations sections
- Remediation priority and status
Normalize common tool output into the PwnReport schema. Importers should be added one at a time with fixtures and tests:
- Nuclei JSONL importer
- Burp Suite issue export importer
- Nmap result importer
- Nessus result importer
- Generic custom JSON importer
The original source files should remain available in the project workspace so the final report can be traced back to the tool output.
- Native PDF export
- Markdown export
- Table of contents
- Client logo and branding fields
- Report metadata and report date
- Multiple report templates
- Light and dark themes
Only after the CLI and schema have matured:
- Multiple projects and report history
- Reusable finding library
- Finding deduplication across assessments
- Scope and asset management
- Review and approval workflow
- Optional local web interface
- Optional team collaboration
The roadmap does not make PwnReport responsible for reconnaissance or exploitation. Scanner and assessment tools remain separate inputs, while PwnReport focuses on normalization, validation, and report delivery.
Run the standard-library test suite:
python3 -m unittest discover -s tests -vMIT