<!-- Copyright (c) 2026 defconxt. All rights reserved. -->
<!-- Licensed under AGPL-3.0 — see LICENSE file for details. -->
---
name: building-vulnerability-report-generators
description: >-
  Build automated vulnerability report generators that transform raw scanner
  output (Nmap, Nessus, Nuclei, Semgrep) into structured reports with CVSS
  scoring, remediation guidance, executive summaries, and multiple output
  formats (JSON, Markdown, HTML, PDF).
domain: cybersecurity
subdomain: automation-scripting
tags:
  - vulnerability-management
  - reporting
  - cvss
  - remediation
  - nessus
  - nuclei
  - compliance
version: "1.0"
author: defconxt
license: AGPL-3.0
metadata:
  mitre-attack: []
---

# Building Vulnerability Report Generators

## Overview

Vulnerability reports bridge the gap between scanner output and stakeholder action.
This skill automates the transformation of raw scan data into actionable reports
with severity prioritization, CVSS scoring, CWE mapping, remediation steps, and
executive summaries suitable for technical teams and management audiences.

Mode: `[MODE: BLUE]` — Vulnerability management and reporting.

## Prerequisites

| Requirement | Details |
|---|---|
| Python 3.10+ with `jinja2` for templating (`pip install jinja2`) | Required |
| Scanner output | Nmap XML, Nessus CSV/JSON, Nuclei JSON, Semgrep JSON |
| Optional | `weasyprint` for PDF generation (`pip install weasyprint`) |

## Key Concepts

### Finding Normalization

```python
def normalize_finding(raw: dict, source: str) -> dict:
    """Normalize scanner findings to common format."""
    return {
        "id": raw.get("id") or raw.get("plugin_id") or raw.get("rule_id"),
        "title": raw.get("name") or raw.get("info", {}).get("name", ""),
        "severity": raw.get("severity", "info").lower(),
        "cvss": raw.get("cvss", 0.0),
        "cwe": raw.get("cwe", []),
        "cve": raw.get("cve", []),
        "description": raw.get("description", ""),
        "remediation": raw.get("remediation") or raw.get("solution", ""),
        "affected_host": raw.get("host") or raw.get("ip", ""),
        "affected_port": raw.get("port", ""),
        "evidence": raw.get("evidence") or raw.get("output", ""),
        "source": source,
    }
```

### Severity Statistics

```python
from collections import Counter

def severity_stats(findings: list[dict]) -> dict:
    """Generate severity distribution statistics."""
    counts = Counter(f["severity"] for f in findings)
    return {
        "critical": counts.get("critical", 0),
        "high": counts.get("high", 0),
        "medium": counts.get("medium", 0),
        "low": counts.get("low", 0),
        "info": counts.get("info", 0),
        "total": len(findings),
    }
```

### Markdown Report Template

```python
def generate_markdown(findings: list[dict], stats: dict) -> str:
    """Generate Markdown vulnerability report."""
    lines = ["# Vulnerability Assessment Report\n"]
    lines.append(f"**Total Findings:** {stats['total']}\n")
    lines.append(f"| Severity | Count |\n|----------|-------|\n")
    for sev in ["critical", "high", "medium", "low", "info"]:
        lines.append(f"| {sev.title()} | {stats[sev]} |")
    lines.append("\n## Findings\n")
    for i, f in enumerate(findings, 1):
        lines.append(f"### [{f['severity'].upper()}] {f['title']}\n")
        lines.append(f"- **Host:** {f['affected_host']}:{f['affected_port']}")
        lines.append(f"- **CVSS:** {f['cvss']}")
        if f["cve"]:
            lines.append(f"- **CVE:** {', '.join(f['cve'])}")
        lines.append(f"- **Description:** {f['description'][:200]}")
        lines.append(f"- **Remediation:** {f['remediation'][:200]}\n")
    return "\n".join(lines)
```

## Workflow

### Step 1: Parse Scanner Output

```bash
node scripts/agent.js --action parse --input /tmp/nuclei-results.json --format nuclei
```

### Step 2: Generate Markdown Report

```bash
node scripts/agent.js --action report --input /tmp/nuclei-results.json --format nuclei --output /tmp/vuln-report.md
```

### Step 3: Generate JSON Summary

```bash
node scripts/agent.js --action summary --input /tmp/nuclei-results.json --format nuclei
```

## Verification

- [ ] Parser handles Nmap XML, Nuclei JSON, Semgrep JSON formats
- [ ] Severity statistics are accurate across all finding types
- [ ] Markdown report renders correctly with proper formatting
- [ ] CVSS scores are preserved from source data
- [ ] Remediation guidance is included for each finding

## References

- [CVSS v3.1 Specification](https://www.first.org/cvss/v3.1/specification-document)
- [CWE List](https://cwe.mitre.org/data/index.html)
- [OWASP Testing Guide](https://owasp.org/www-project-web-security-testing-guide/)
- [Nuclei Templates](https://github.com/projectdiscovery/nuclei-templates)
