| # API Reference — `report/` | |
| ## `report/__init__.py` — public exports | |
| ```python | |
| from report import generate_html_report, generate_sarif, REMEDIATION | |
| ``` | |
| --- | |
| ## `report/html.py` | |
| ### `generate_html_report(findings, scan_meta)` | |
| ```python | |
| def generate_html_report(findings: List[dict], scan_meta: dict) -> str | |
| ``` | |
| Build a self-contained, print-friendly HTML report string. | |
| **Parameters:** | |
| | Parameter | Type | Description | | |
| |-----------|------|-------------| | |
| | `findings` | `List[dict]` | Normalized finding dicts (from `make_finding`) | | |
| | `scan_meta` | `dict` | Metadata injected into the report | | |
| **`scan_meta` keys:** | |
| | Key | Default | Description | | |
| |-----|---------|-------------| | |
| | `"title"` | `"Security Scan Report"` | `<title>` and `<h1>` | | |
| | `"footer"` | `"HF Security Scanner"` | Footer text | | |
| | `"repo"` | `""` | Repository URL shown in header | | |
| | `"scanned_at"` | auto | ISO timestamp | | |
| **Returns:** Complete `<!DOCTYPE html>...` string. | |
| **Features:** | |
| - Summary cards: severity counts (ERROR / WARNING / INFO), confidence distribution, category split (security / performance). | |
| - Top OWASP categories section (top 8 by frequency). | |
| - Per-finding cards with: severity badge, confidence badge, category badge, tool/rule badge, OWASP tag(s), message, file:line, and remediation hint. | |
| - All user content is HTML-escaped (XSS-safe). | |
| - Severity aliases: `HIGH → ERROR`, `MEDIUM → WARNING`, `LOW → INFO`. | |
| **Example:** | |
| ```python | |
| from report import generate_html_report | |
| html = generate_html_report(findings, {"title": "My Project Scan", "repo": "github.com/org/repo"}) | |
| Path("report.html").write_text(html, encoding="utf-8") | |
| ``` | |
| --- | |
| ### Internal functions | |
| #### `_render_finding(f)` | |
| ```python | |
| def _render_finding(f: dict) -> str | |
| ``` | |
| Render a single finding dict as an HTML `<div class="finding ...">` block. | |
| #### `_aggregate(findings)` | |
| ```python | |
| def _aggregate(findings: List[dict]) -> dict | |
| ``` | |
| Compute summary statistics. Returns: | |
| ```python | |
| { | |
| "severity": {"ERROR": int, "WARNING": int, "INFO": int}, | |
| "confidence": {"confirmed": int, "likely": int, "possible": int}, | |
| "category": {"security": int, "performance": int}, | |
| "owasp": {"A01:2021-...": int, ...}, | |
| } | |
| ``` | |
| --- | |
| ## `report/sarif.py` | |
| ### `generate_sarif(findings, scan_meta)` | |
| ```python | |
| def generate_sarif(findings: List[dict], scan_meta: dict) -> dict | |
| ``` | |
| Build a SARIF 2.1.0 document as a Python dict (serialize with `json.dumps`). | |
| **Parameters:** | |
| | Parameter | Type | Description | | |
| |-----------|------|-------------| | |
| | `findings` | `List[dict]` | Normalized finding dicts | | |
| | `scan_meta` | `dict` | Metadata (same keys as HTML report) | | |
| **Returns:** `dict` conforming to `https://json.schemastore.org/sarif-2.1.0.json`. | |
| **GitHub Advanced Security compatibility:** | |
| - Upload the serialized SARIF file using `github/codeql-action/upload-sarif`. | |
| - `properties.security-severity` is a float string (`"9.0"`) enabling GitHub's severity triage. | |
| - `partialFingerprints.primaryLocationLineHash` enables GitHub to deduplicate findings across runs. | |
| - File paths are normalized to forward-slash, drive letters stripped (`C:\path` → `path`). | |
| **Example:** | |
| ```python | |
| import json | |
| from report import generate_sarif | |
| sarif = generate_sarif(findings, {"repo": "https://github.com/org/repo"}) | |
| Path("results.sarif").write_text(json.dumps(sarif, indent=2), encoding="utf-8") | |
| ``` | |
| ### Severity → SARIF level mapping | |
| | Severity | Confidence | SARIF `level` | `security-severity` | | |
| |----------|-----------|--------------|---------------------| | |
| | ERROR | confirmed | `error` | 9.0 | | |
| | ERROR | likely | `error` | 7.5 | | |
| | ERROR | possible | `warning` | 5.5 | | |
| | HIGH | confirmed | `error` | 8.5 | | |
| | WARNING | confirmed | `warning` | 4.5 | | |
| | WARNING | likely | `warning` | 4.0 | | |
| | WARNING | possible | `warning` | 3.0 | | |
| | INFO | confirmed | `note` | 2.5 | | |
| | INFO | likely | `note` | 2.0 | | |
| | INFO | possible | `note` | 1.5 | | |
| ### Internal functions | |
| #### `_fingerprint(finding)` | |
| ```python | |
| def _fingerprint(finding: dict) -> str | |
| ``` | |
| SHA-256 fingerprint of `tool:rule:file:line:message` (first 16 hex chars). Used for `partialFingerprints.primaryLocationLineHash`. | |
| #### `_build_rules_catalog(findings)` | |
| ```python | |
| def _build_rules_catalog(findings: List[dict]) -> List[dict] | |
| ``` | |
| Build the `tool.driver.rules[]` catalog — one entry per unique `rule` ID, with `shortDescription`, `helpUri` (OWASP link), and `security-severity`. | |
| #### `_result_for_finding(finding)` | |
| ```python | |
| def _result_for_finding(finding: dict) -> dict | |
| ``` | |
| Convert one finding dict to a SARIF `result` object. Handles: | |
| - Windows path normalization (strips drive letters). | |
| - Invalid / non-positive line numbers (normalized to `1`). | |
| #### `_help_uri(owasp)` | |
| ```python | |
| def _help_uri(owasp: Any) -> str | |
| ``` | |
| Return the first matching OWASP help URL for the given OWASP tag list. Falls back to `_TOOL_URI` if no match. | |
| --- | |
| ## `report/remediation.py` | |
| ### `REMEDIATION` | |
| ```python | |
| REMEDIATION: dict[str, str] | |
| ``` | |
| A mapping from rule ID / finding type to a short plain-English fix hint. Used by `make_finding()` in `core/models.py` — if `remediation=None` is passed, the registry is consulted. | |
| **To add a hint:** | |
| ```python | |
| # report/remediation.py | |
| REMEDIATION = { | |
| "B602": "Avoid shell=True; use subprocess.run() with a list.", | |
| "MY-RULE": "Replace foo() with safe_foo().", | |
| ... | |
| } | |
| ``` | |
| --- | |
| ## `report/styles.py` | |
| ### `REPORT_CSS` | |
| Embedded CSS string for the HTML report. Imported by `report/html.py`. | |
| ### `FP_GUIDE_HTML` | |
| HTML fragment with a false-positive triage guide appended to every report. | |