feat(cra): hardware path — derive cyber findings from networked components

For hardware CE projects (no repo) each networked component (controller/hmi/
gateway/drive/remote_access/sensor) yields typical ICS vulnerability CLASSES
(real CWE + "CISA-ICS — product-specific check" framing, NO fabricated CVEs);
they flow through the same CRA engine. /assess accepts components[]. MappedFinding
now echoes title/location/cwe so the response is self-contained for any finding
source. Live CISA-ICS/NVD per-product CVE lookup is the later enrichment.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-06-14 12:37:22 +02:00
parent 398eaf3c36
commit 437c2c8fa1
4 changed files with 115 additions and 3 deletions
@@ -90,6 +90,9 @@ class ScannerFinding:
@dataclass
class MappedFinding:
finding_id: str
title: str = ""
location: str = ""
cwe: str = ""
requirement_ids: list = field(default_factory=list)
primary_requirement: str = ""
annex_anchor: str = ""
@@ -172,7 +175,8 @@ def map_finding(f: ScannerFinding) -> MappedFinding:
finding_sev = (f.severity or _sev_from_cvss(f.cvss)).upper()
if not reqs:
return MappedFinding(
finding_id=f.id, risk_level=_SEV_BY_RANK.get(_rank(finding_sev), "LOW"),
finding_id=f.id, title=f.title, location=f.location, cwe=f.cwe,
risk_level=_SEV_BY_RANK.get(_rank(finding_sev), "LOW"),
rationale="Kein eindeutiger CRA-Anforderungsbezug erkannt — manuelle Pruefung.",
unmapped=True, safety_impact=f.safety_impact, exploited=f.exploited,
)
@@ -186,6 +190,9 @@ def map_finding(f: ScannerFinding) -> MappedFinding:
refs = security_refs_for(reqs)
return MappedFinding(
finding_id=f.id,
title=f.title,
location=f.location,
cwe=f.cwe,
requirement_ids=reqs,
primary_requirement=primary["req_id"],
annex_anchor=primary.get("annex_anchor", ""),