File size: 5,772 Bytes
5248e3b | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 | # 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.
|