Skip to content

Commit 6e2e9b1

Browse files
AradTraubclaude
andcommitted
Show the CVE row only for package vulnerabilities
The rich printer added a CVEs row to every SCA detection, so unmaintained and license findings - neither of which carries a vulnerability_id - rendered an empty row. The CVE now comes from the policy-keyed details alongside the first patched version, so a policy that has no CVE simply does not show the field. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent 992c171 commit 6e2e9b1

3 files changed

Lines changed: 34 additions & 7 deletions

File tree

cycode/cli/printers/rich_printer.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ def __add_secret_scan_related_rows(details_table: Table, detection: 'Detection')
8787
def __add_sca_scan_related_rows(details_table: Table, detection: 'Detection') -> None:
8888
detection_details = detection.detection_details
8989

90-
details_table.add_row('CVEs', get_detection_clickable_cwe_cve(consts.SCA_SCAN_TYPE, detection))
9190
details_table.add_row('Package', detection_details.get('package_name'))
9291
details_table.add_row('Version', detection_details.get('package_version'))
9392

cycode/cli/printers/utils/sca_policy_details.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
from cycode.cli.consts import (
44
LICENSE_COMPLIANCE_POLICY_ID,
55
PACKAGE_VULNERABILITY_POLICY_ID,
6+
SCA_SCAN_TYPE,
67
UNMAINTAINED_PACKAGE_POLICY_ID,
78
)
9+
from cycode.cli.printers.utils.detection_data import get_detection_clickable_cwe_cve
810
from cycode.cli.printers.utils.sca_ossf import get_maintained_score, get_ossf_report_url, get_ossf_score
911

1012
if TYPE_CHECKING:
@@ -15,7 +17,10 @@
1517

1618
def _package_vulnerability_details(detection: 'Detection') -> list[tuple[str, str]]:
1719
alert = detection.detection_details.get('alert') or {}
18-
return [('First patched version', alert.get('first_patched_version') or 'Not fixed')]
20+
return [
21+
('CVEs', get_detection_clickable_cwe_cve(SCA_SCAN_TYPE, detection) or _NOT_AVAILABLE),
22+
('First patched version', alert.get('first_patched_version') or 'Not fixed'),
23+
]
1924

2025

2126
def _license_compliance_details(detection: 'Detection') -> list[tuple[str, str]]:

tests/cli/printers/utils/test_sca_policy_details.py

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,26 @@ def _make_detection(policy_id: str, **details: object) -> Detection:
1818
)
1919

2020

21-
def test_package_vulnerability_reports_the_patched_version() -> None:
22-
detection = _make_detection(PACKAGE_VULNERABILITY_POLICY_ID, alert={'first_patched_version': '4.17.21'})
21+
def test_package_vulnerability_reports_the_cve_and_the_patched_version() -> None:
22+
detection = _make_detection(
23+
PACKAGE_VULNERABILITY_POLICY_ID,
24+
alert={'first_patched_version': '4.17.21'},
25+
vulnerability_id='CVE-2021-23337',
26+
)
2327

24-
assert get_sca_policy_details(detection) == [('First patched version', '4.17.21')]
28+
assert get_sca_policy_details(detection) == [
29+
('CVEs', '[link=https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-23337]CVE-2021-23337[/]'),
30+
('First patched version', '4.17.21'),
31+
]
2532

2633

27-
def test_package_vulnerability_without_a_patch() -> None:
34+
def test_package_vulnerability_without_a_patch_or_a_cve() -> None:
2835
detection = _make_detection(PACKAGE_VULNERABILITY_POLICY_ID, alert={'first_patched_version': None})
2936

30-
assert get_sca_policy_details(detection) == [('First patched version', 'Not fixed')]
37+
assert get_sca_policy_details(detection) == [
38+
('CVEs', 'N/A'),
39+
('First patched version', 'Not fixed'),
40+
]
3141

3242

3343
def test_license_compliance_reports_the_license() -> None:
@@ -69,6 +79,19 @@ def test_unmaintained_package_without_a_scorecard() -> None:
6979
]
7080

7181

82+
def test_only_package_vulnerability_reports_a_cve() -> None:
83+
"""A CVE belongs to the vulnerability policy alone.
84+
85+
It used to be rendered for every SCA detection, so an unmaintained or license finding - neither of which
86+
carries a vulnerability_id - showed an empty CVEs row.
87+
"""
88+
for policy_id in (LICENSE_COMPLIANCE_POLICY_ID, UNMAINTAINED_PACKAGE_POLICY_ID):
89+
detection = _make_detection(policy_id, vulnerability_id='CVE-2021-23337')
90+
91+
labels = [label for label, _ in get_sca_policy_details(detection)]
92+
assert 'CVEs' not in labels
93+
94+
7295
def test_an_unregistered_policy_contributes_nothing() -> None:
7396
"""A policy with no entry must stay silent rather than borrow another policy's fields.
7497

0 commit comments

Comments
 (0)