Skip to content

Reports

blackbuble edited this page Oct 30, 2026 · 1 revision

Reports & Compliance

Report generation system documentation — HTML, Word (.docx), evidence vault, and compliance tagging.


Output Formats

PentestAI produces the following report formats from a single session:

Format Command Target Audience
HTML report Internal review, quick sharing
Word (.docx) report docx Client, management, compliance
HTML (without AI) report quick Internal review, fast, no LLM
SARIF 2.1.0 report sarif CI, code scanning, DevSecOps
PDF report pdf Client delivery, archival
All formats report all Complete package

SARIF exports validated findings only by default. Use report sarif all to include candidates; each result carries validationStatus in its properties. PDF rendering uses headless Chromium (Playwright).


Word Report (.docx)

Generator reports/generate_docx.js (Node.js) + ReportGenerator.generate_docx() (Python wrapper).

Contents of the Word report:

  1. Cover page — target, date, CONFIDENTIAL classification
  2. Executive summary — summary in CFO language with a risk table per severity
  3. Per-finding sections — colored severity badge, evidence, PoC curl commands, OWASP/CWE tags
  4. Appendix A — scope expansion log (if there are expansion requests)
  5. Appendix B — raw evidence with SHA-256 hashes
from reports.generator import ReportGenerator

gen = ReportGenerator(session)
path = gen.generate_docx()           # returns Path to the .docx file
path = gen.generate_docx(ai_content={"executive_summary": "..."})  # with AI summary

Requirement: Node.js (for generate_docx.js)

node --version   # make sure it is installed

HTML Report

gen = ReportGenerator(session)
paths = gen.generate()
# paths["html"]     → Path to .html
# paths["markdown"] → Path to .md
report          # with AI enhancement (requires LLM)
report quick    # without AI, directly from session data

Evidence Vault

All evidence is attached to a specific finding, immutable with a SHA-256 hash.

# Attach evidence to a finding
h = session.attach_evidence(finding_id, "HTTP/1.1 200 OK\nroot:x:0:0", label="passwd_leak")
# → returns 16-char hash, e.g. "a3f8e2b1c9d4f7e0"

# Verify integrity
result = session.verify_evidence(finding_id)
# → {"status": "ok", "verified": 2, "files": [...]}
# → {"status": "tampered", "tampered": ["20241019_evidence.txt"]}

# Export all evidence as a ZIP bundle
bundle = session.export_evidence_bundle()
# → ZIP contains: session.json, all evidence files, INDEX.txt with hashes
evidence attach <finding_id> [label]   # paste content from stdin
evidence verify [finding_id]           # verify hash integrity
evidence export                        # ZIP bundle of all evidence
evidence fp <finding_id>               # mark as false positive

Fields in Finding:

  • evidence_hashes: list[str] — SHA-256[:16] of each evidence item attached
  • false_positive: bool — flagged as FP by the operator
  • remediated: bool — already fixed by the client

Compliance Tagger

reports/compliance.py — auto-tagging of every finding with standard frameworks.

from reports.compliance import tag_finding, ComplianceTags

tags = tag_finding("SQL Injection", severity="High")
# ComplianceTags(
#   owasp=["A03:2021 - Injection"],
#   cwe=[89],
#   cvss_score=8.8,
#   cvss_vector="AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N",
#   epss_score=0.97,
#   epss_percentile=99,
# )

Supported frameworks:

  • OWASP Top 10 2021 (A01–A10)
  • CWE identifiers
  • CVSS 4.0 base score + vector
  • EPSS (Exploit Prediction Scoring System) score + percentile

PoC Generator

agents/poc.py — capture HTTP request/response and produce reproduction steps.

from agents.poc import PoCRunner

runner = PoCRunner(session)
packages = runner.generate_all()   # all findings

for pkg in packages:
    print(pkg.reproduction_steps)  # list of steps
    for ev in pkg.evidence:
        print(ev.to_curl())        # curl command that can be reproduced
poc    # generate PoCs for all findings in the session

PoCPackage output:

  • reproduction_steps: list[str] — steps to reproduce
  • evidence: list[HTTPEvidence] — HTTP request/response captures
  • curl_commands: list[str] — curl commands that can be run directly

Report + Evidence Integration in Docx

When generate_docx() runs, it automatically:

  1. Collects all PoCPackage from PoCRunner
  2. Collects evidence from session.attach_evidence()
  3. Attaches curl commands and response snippets to each finding section
  4. Includes the scope expansion log in Appendix A
  5. Includes raw evidence with hashes in Appendix B

PTES Report (Phase 6)

Report format according to Penetration Testing Execution Standard.

from reports.ptes import PTESReportGenerator

gen = PTESReportGenerator(session)
json_path = gen.generate_json()       # machine-readable
md_path   = gen.generate_markdown()  # human-readable
ptes    # generate both from the shell

Contents of the PTES report:

  • Executive summary with overall risk rating (CRITICAL/HIGH/MEDIUM/LOW)
  • Per-finding with PTES phase mapping (Phase 2/4/5/6)
  • Business impact per finding (non-technical language)
  • Top recommendation for management
  • Scope expansion log

Automatic PTES phase mapping based on tool:

Tool PTES Phase
nmap, http, subdomain, osint Phase 2 — Intelligence Gathering
gobuster, nikto, waf_detect Phase 4 — Vulnerability Analysis
sqlmap, metasploit, SSTI/XXE Phase 5 — Exploitation
privesc, ad_enum, kerberoast Phase 6 — Post Exploitation

ISO 27001 Risk Register (Phase 6)

Export findings as a risk register according to ISO/IEC 27001:2022 Annex A.

from reports.ptes import ISO27001RiskRegister

gen  = ISO27001RiskRegister(session)
path = gen.generate()    # returns Path to the JSON file
iso27001    # generate from the shell

JSON format:

{
  "standard": "ISO/IEC 27001:2022 Annex A",
  "risks": [
    {
      "risk_id": "R-a3f8",
      "asset": "http://10.0.0.1/",
      "vulnerability": "SQL Injection",
      "likelihood": "4/5",
      "impact": "4/5",
      "risk_score": 16,
      "iso_controls": ["A.14.2.5 Secure system engineering principles"],
      "treatment": "Use parameterized queries",
      "treatment_status": "open",
      "residual_risk": "High"
    }
  ]
}

Risk scoring: likelihood × impact (1-5 scale), sorted descending. ISO controls are mapped automatically from the finding's OWASP tags. Residual risk is automatically "Low" when finding.remediated = True.

Clone this wiki locally