Skip to content

Commit ff9edd1

Browse files
committed
fix: always include unchanged alerts in FOSSA output
FOSSA's /api/v2/issues endpoint returns a point-in-time snapshot of all issues at the scan revision, not only diff-new ones. The previous implementation only included unchanged alerts when --strict-blocking was set, causing FOSSA-mode output to under-represent project-wide findings compared to the typical FOSSA pipeline.
1 parent fbce1e4 commit ff9edd1

2 files changed

Lines changed: 39 additions & 2 deletions

File tree

socketsecurity/fossa_compat.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -323,9 +323,13 @@ def _build_quality_entry(
323323

324324

325325
def _iter_selected_issues(diff_report: Diff, config: CliConfig) -> Iterable[Issue]:
326+
"""Yield all currently-present issues (new + unchanged) to match FOSSA's
327+
/api/v2/issues behavior, which returns a point-in-time snapshot of all
328+
issues at the scan revision, not only diff-new ones. The `config` argument
329+
is retained for signature stability but no longer gates output.
330+
"""
326331
yield from getattr(diff_report, "new_alerts", []) or []
327-
if getattr(config, "strict_blocking", False):
328-
yield from getattr(diff_report, "unchanged_alerts", []) or []
332+
yield from getattr(diff_report, "unchanged_alerts", []) or []
329333

330334

331335
def _classify_issue(issue: Issue) -> str:

tests/unit/test_fossa_compat.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,3 +435,36 @@ def test_vulnerability_version_ranges_sourced_from_socket_fields():
435435
assert entry["patchedVersionRanges"] == ["2.31.1"]
436436
assert entry["remediation"]["partialFix"] == "2.31.1"
437437
assert entry["remediation"]["completeFix"] == "2.31.1"
438+
439+
440+
def test_fossa_payload_includes_unchanged_alerts_regardless_of_strict_blocking():
441+
"""FOSSA emits all currently-present issues at the scan revision, not just
442+
diff-new ones. So `unchanged_alerts` must always flow into the payload,
443+
independent of the --strict-blocking flag."""
444+
new_issue = Issue(
445+
type="criticalCVE", severity="high", key="NEW",
446+
pkg_type="pypi", pkg_name="a", pkg_version="1.0",
447+
props={"cveId": "CVE-2024-NEW", "ghsaId": "GHSA-new"},
448+
)
449+
unchanged_issue = Issue(
450+
type="criticalCVE", severity="high", key="OLD",
451+
pkg_type="pypi", pkg_name="b", pkg_version="1.0",
452+
props={"cveId": "CVE-2024-OLD", "ghsaId": "GHSA-old"},
453+
)
454+
diff = Diff(new_alerts=[new_issue], unchanged_alerts=[unchanged_issue])
455+
456+
# strict_blocking off (default):
457+
config_loose = CliConfig.from_args(["--api-token", "test", "--legal-format", "fossa"])
458+
payload_loose = build_fossa_report_payload(diff, config_loose)
459+
loose_cves = sorted(v["cve"] for v in payload_loose["vulnerability"])
460+
assert loose_cves == ["CVE-2024-NEW", "CVE-2024-OLD"], (
461+
"FOSSA mode must include unchanged_alerts even without --strict-blocking"
462+
)
463+
464+
# strict_blocking on — same result (always include both):
465+
config_strict = CliConfig.from_args(
466+
["--api-token", "test", "--legal-format", "fossa", "--strict-blocking"]
467+
)
468+
payload_strict = build_fossa_report_payload(diff, config_strict)
469+
strict_cves = sorted(v["cve"] for v in payload_strict["vulnerability"])
470+
assert strict_cves == loose_cves

0 commit comments

Comments
 (0)