(number: int, finding: dict[str, Any])
| 259 | |
| 260 | |
| 261 | def _finding_section(number: int, finding: dict[str, Any]) -> list[str]: |
| 262 | validation = finding.get("validation") if isinstance(finding.get("validation"), dict) else {} |
| 263 | raw_root_cause = finding.get("rootCause") |
| 264 | root_cause = raw_root_cause if isinstance(raw_root_cause, dict) else {} |
| 265 | attack_path = finding.get("attackPath") if isinstance(finding.get("attackPath"), dict) else {} |
| 266 | dataflow = attack_path.get("dataflow") if isinstance(attack_path.get("dataflow"), dict) else {} |
| 267 | reachability = ( |
| 268 | attack_path.get("reachability") if isinstance(attack_path.get("reachability"), dict) else {} |
| 269 | ) |
| 270 | severity = finding["severity"] |
| 271 | validation_summary = _text( |
| 272 | validation.get("summary"), |
| 273 | f"{finding['confidence']['rationale']} Validation details were not recorded separately.", |
| 274 | ) |
| 275 | validation_evidence = _strings(validation.get("evidence")) |
| 276 | validation_counterevidence = _strings(validation.get("counterEvidence")) |
| 277 | root_cause_summary = _text( |
| 278 | raw_root_cause if isinstance(raw_root_cause, str) else root_cause.get("summary"), |
| 279 | "", |
| 280 | ) |
| 281 | root_cause_code_evidence = _root_cause_code_evidence(finding, root_cause) |
| 282 | validation_code_evidence = _section_code_evidence(finding, validation) |
| 283 | attack_path_code_evidence = _section_code_evidence(finding, attack_path) |
| 284 | dataflow_summary = _text( |
| 285 | dataflow.get("summary"), |
| 286 | f"The canonical finding records the affected path at {_locations(finding)}, but no expanded source-to-sink narrative was recorded.", |
| 287 | ) |
| 288 | reachability_summary = _text( |
| 289 | reachability.get("summary"), |
| 290 | "Reachability was not recorded beyond the canonical finding summary and affected locations.", |
| 291 | ) |
| 292 | severity_rationale = _text( |
| 293 | severity.get("rationale"), |
| 294 | f"The scan assigned {severity['level']} severity; no separate canonical severity rationale was recorded.", |
| 295 | ) |
| 296 | severity_change = _text( |
| 297 | severity.get("changeConditions"), |
| 298 | "Additional runtime or deployment evidence could raise or lower this severity.", |
| 299 | ) |
| 300 | remediation_tests = _strings(finding.get("remediationTests")) |
| 301 | preventive_controls = _strings(finding.get("preventiveControls")) |
| 302 | cwes = ", ".join(finding["taxonomy"]["cwe"]) or "none" |
| 303 | title = _text(finding["title"], "Untitled finding") |
| 304 | lines = [ |
| 305 | f'<a id="finding-{number}"></a>', |
| 306 | "", |
| 307 | f"### [{number}] {title}", |
| 308 | "", |
| 309 | "| Field | Value |", |
| 310 | "| --- | --- |", |
| 311 | f"| Severity | {_cell(severity['level'])} |", |
| 312 | f"| Confidence | {_cell(finding['confidence']['level'])} |", |
| 313 | f"| Confidence rationale | {_cell(finding['confidence']['rationale'])} |", |
| 314 | f"| Category | {_cell(finding['taxonomy']['category'])} |", |
| 315 | f"| CWE | {_cell(cwes)} |", |
| 316 | f"| Affected lines | {_cell(_locations(finding))} |", |
| 317 | "", |
| 318 | "#### Summary", |
no test coverage detected