API Reference β report/
report/__init__.py β public exports
from report import generate_html_report, generate_sarif, REMEDIATION
report/html.py
generate_html_report(findings, scan_meta)
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:
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)
def _render_finding(f: dict) -> str
Render a single finding dict as an HTML <div class="finding ..."> block.
_aggregate(findings)
def _aggregate(findings: List[dict]) -> dict
Compute summary statistics. Returns:
{
"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)
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-severityis a float string ("9.0") enabling GitHub's severity triage.partialFingerprints.primaryLocationLineHashenables GitHub to deduplicate findings across runs.- File paths are normalized to forward-slash, drive letters stripped (
C:\pathβpath).
Example:
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)
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)
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)
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)
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
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:
# 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.