fix(vuln): survive OOM kills, isolate bad upstream strings, label findings per line
Review findings on the integrated scanner: - An OOM kill no longer wedges the loop: inFlight is persisted before each scan, and on restart that image is marked failed and sits out full runs for 20h. - One bad upstream string can no longer freeze the report: safe_url requires an exact lowercase scheme, acceptance reasons are bounded, /triage urls use the same rule, and report.build repairs or drops any entry the schema would refuse. lastCompleteRunAt advances only after a report is actually published. - The private registry reports credential-required, not failed: VULN_PRIVATE_REGISTRIES names it, and Trivy is not invoked. - loadError clears after a full run against a good inventory. - Every image under platform/vuln-scanner stays out of Renovate auto-merge. - The page labels status and target state per line, and mixed acceptance reads as mixed. The Keycloak client is still an operator action: its key must go in an existing encrypted file that an agent must not modify. platform/vuln-scanner/README.md has the exact steps. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
4c82c64b2f
commit
d8b25a67fe
15 files changed
+557
-43
No files matched your search
@@ -170,6 +170,39 @@ _, _, body = render()
|
||||
check("default view excludes nothing", all(f["id"] in body for f in REPORT["findings"]))
|
||||
check("remediation column shows pr-open with a link", 'href="https://gitea.test/pulls/1"' in body and "pr-open" in body)
|
||||
|
||||
# Status and state belong to the line they describe (R-VULN-04).
|
||||
images = [t for t in REPORT["targets"] if t["type"] == "image" and t["workloads"]]
|
||||
check("fixture has two image targets with workloads", len(images) >= 2)
|
||||
mixed = copy.deepcopy(REPORT)
|
||||
first, second = next(t for t in mixed["targets"] if t["id"] == images[0]["id"]), next(t for t in mixed["targets"] if t["id"] == images[1]["id"])
|
||||
first["state"], first["reason"] = "scanned", None
|
||||
second["state"], second["reason"] = "stale", "last success long ago"
|
||||
base = dict(REPORT["findings"][0], id="CVE-MIXED")
|
||||
base.pop("acceptance", None)
|
||||
mixed["findings"] = [
|
||||
dict(base, targetId=first["id"], status="accepted", acceptance={"reason": "only-on-the-first", "expires": "2026-12-01"}),
|
||||
dict(base, targetId=second["id"], status="fix-available"),
|
||||
]
|
||||
_, _, body = render(mixed, "view=cves&q=CVE-MIXED")
|
||||
check("a mixed CVE reads as mixed, with counts", "mixed: 1 fix-available, 1 accepted" in body)
|
||||
check("a mixed CVE's row does not carry one image's acceptance", "<td>mixed: 1 fix-available, 1 accepted</td>" in body)
|
||||
first_line = page.e(first["id"]) + " — target scanned — status accepted (only-on-the-first, until 2026-12-01)"
|
||||
second_line = page.e(second["id"]) + " — target stale (last success long ago) — status fix-available"
|
||||
check("the accepted image's line carries its own acceptance", first_line in body)
|
||||
check("the other image's line carries its own status and state", second_line in body)
|
||||
check("no line attaches the acceptance to the unaccepted status", "status fix-available (only-on-the-first" not in body)
|
||||
check("workload lines inside the expansion carry state and status",
|
||||
"target stale (last success long ago) — status fix-available</li>" in body
|
||||
and "containers: " + page.e(", ".join(second["workloads"][0]["containers"]) or "none") + " — target stale" in body)
|
||||
_, _, plain = render(query="view=cves&status=accepted")
|
||||
check("mutation: a uniformly accepted CVE does not read as mixed", "mixed:" not in plain and "CVE-2026-1003" in plain)
|
||||
_, _, body = render(mixed, "view=workloads")
|
||||
check("the workloads images column labels each image's state", page.e(second["id"]) + " — target stale (last success long ago)" in body)
|
||||
check("the workloads expansion labels each finding's status, image and state",
|
||||
"status fix-available — " + page.e(second["id"]) + " — target stale (last success long ago)</li>" in body)
|
||||
check("the workloads expansion keeps an acceptance on its own line",
|
||||
"status accepted (only-on-the-first, until 2026-12-01) — " + page.e(first["id"]) + " — target scanned</li>" in body)
|
||||
|
||||
big = copy.deepcopy(REPORT)
|
||||
big["findings"] = [dict(REPORT["findings"][0], id="CVE-2026-" + format(i, "05d")) for i in range(250)]
|
||||
_, _, body = render(big, "view=cves&size=50&page=2")
|
||||
|
||||
Reference in new issue
Block a user