Skip to content

Commit c8f9b12

Browse files
authored
CM-26869 - Add --severity-threshold support for all scan types (#269)
1 parent 44df1d6 commit c8f9b12

File tree

7 files changed

+63
-9
lines changed

7 files changed

+63
-9
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ The Cycode CLI application offers several types of scans so that you can choose
287287
| `--client-id TEXT` | Specify a Cycode client ID for this specific scan execution |
288288
| `--show-secret BOOLEAN` | Show secrets in plain text. See [Show/Hide Secrets](#showhide-secrets) section for more details. |
289289
| `--soft-fail BOOLEAN` | Run scan without failing, always return a non-error status code. See [Soft Fail](#soft-fail) section for more details. |
290-
| `--severity-threshold [INFO\|LOW\|MEDIUM\|HIGH\|CRITICAL]` | Show only violations at the specified level or higher (supported for the SCA scan type only). |
290+
| `--severity-threshold [INFO\|LOW\|MEDIUM\|HIGH\|CRITICAL]` | Show only violations at the specified level or higher. |
291291
| `--sca-scan` | Specify the SCA scan you wish to execute (`package-vulnerabilities`/`license-compliance`). The default is both |
292292
| `--monitor` | When specified, the scan results will be recorded in the knowledge graph. Please note that when working in `monitor` mode, the knowledge graph will not be updated as a result of SCM events (Push, Repo creation). (Supported for SCA scan type only). |
293293
| `--report` | When specified, a violations report will be generated. A URL link to the report will be printed as an output to the command execution |

cycode/cli/commands/scan/code_scanner.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -713,20 +713,26 @@ def exclude_irrelevant_detections(
713713
) -> List[Detection]:
714714
relevant_detections = _exclude_detections_by_exclusions_configuration(detections, scan_type)
715715
relevant_detections = _exclude_detections_by_scan_type(relevant_detections, scan_type, command_scan_type)
716-
return _exclude_detections_by_severity(relevant_detections, scan_type, severity_threshold)
716+
return _exclude_detections_by_severity(relevant_detections, severity_threshold)
717717

718718

719-
def _exclude_detections_by_severity(
720-
detections: List[Detection], scan_type: str, severity_threshold: str
721-
) -> List[Detection]:
722-
if scan_type != consts.SCA_SCAN_TYPE or severity_threshold is None:
719+
def _exclude_detections_by_severity(detections: List[Detection], severity_threshold: str) -> List[Detection]:
720+
if severity_threshold is None:
723721
return detections
724722

725723
relevant_detections = []
726724
for detection in detections:
727725
severity = detection.detection_details.get('advisory_severity')
726+
if not severity:
727+
severity = detection.severity
728+
728729
if _does_severity_match_severity_threshold(severity, severity_threshold):
729730
relevant_detections.append(detection)
731+
else:
732+
logger.debug(
733+
'Going to ignore violations because they are below the severity threshold, %s',
734+
{'severity': severity, 'severity_threshold': severity_threshold},
735+
)
730736

731737
return relevant_detections
732738

@@ -861,10 +867,11 @@ def _generate_unique_id() -> UUID:
861867

862868
def _does_severity_match_severity_threshold(severity: str, severity_threshold: str) -> bool:
863869
detection_severity_value = Severity.try_get_value(severity)
864-
if detection_severity_value is None:
870+
severity_threshold_value = Severity.try_get_value(severity_threshold)
871+
if detection_severity_value is None or severity_threshold_value is None:
865872
return True
866873

867-
return detection_severity_value >= Severity.try_get_value(severity_threshold)
874+
return detection_severity_value >= severity_threshold_value
868875

869876

870877
def _get_scan_result(

cycode/cli/commands/scan/scan_command.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
@click.option(
6767
'--severity-threshold',
6868
default=None,
69-
help='Show violations only for the specified level or higher (supported for SCA scan types only).',
69+
help='Show violations only for the specified level or higher.',
7070
type=click.Choice([e.name for e in Severity]),
7171
required=False,
7272
)

cycode/cli/models.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class Severity(Enum):
4343

4444
@staticmethod
4545
def try_get_value(name: str) -> any:
46+
name = name.upper()
4647
if name not in Severity.__members__:
4748
return None
4849

tests/cli/commands/scan/test_code_scanner.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import os
22

33
from cycode.cli import consts
4+
from cycode.cli.commands.scan.code_scanner import _does_severity_match_severity_threshold
45
from cycode.cli.files_collector.excluder import _is_file_relevant_for_sca_scan
56
from cycode.cli.files_collector.path_documents import _generate_document
67
from cycode.cli.models import Document
@@ -72,3 +73,24 @@ def test_generate_document() -> None:
7273
assert isinstance(generated_tfplan_document, Document)
7374
assert generated_tfplan_document.path.endswith('.tf')
7475
assert generated_tfplan_document.is_git_diff_format == is_git_diff
76+
77+
78+
def test_does_severity_match_severity_threshold() -> None:
79+
assert _does_severity_match_severity_threshold('INFO', 'LOW') is False
80+
81+
assert _does_severity_match_severity_threshold('LOW', 'LOW') is True
82+
assert _does_severity_match_severity_threshold('LOW', 'MEDIUM') is False
83+
84+
assert _does_severity_match_severity_threshold('MEDIUM', 'LOW') is True
85+
assert _does_severity_match_severity_threshold('MEDIUM', 'MEDIUM') is True
86+
assert _does_severity_match_severity_threshold('MEDIUM', 'HIGH') is False
87+
88+
assert _does_severity_match_severity_threshold('HIGH', 'MEDIUM') is True
89+
assert _does_severity_match_severity_threshold('HIGH', 'HIGH') is True
90+
assert _does_severity_match_severity_threshold('HIGH', 'CRITICAL') is False
91+
92+
assert _does_severity_match_severity_threshold('CRITICAL', 'HIGH') is True
93+
assert _does_severity_match_severity_threshold('CRITICAL', 'CRITICAL') is True
94+
95+
assert _does_severity_match_severity_threshold('NON_EXISTENT', 'LOW') is True
96+
assert _does_severity_match_severity_threshold('LOW', 'NON_EXISTENT') is True

tests/cli/models/__init__.py

Whitespace-only changes.

tests/cli/models/test_severity.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
from cycode.cli.models import Severity
2+
3+
4+
def test_try_get_value() -> None:
5+
assert Severity.try_get_value('info') == -1
6+
assert Severity.try_get_value('iNfO') == -1
7+
8+
assert Severity.try_get_value('INFO') == -1
9+
assert Severity.try_get_value('LOW') == 0
10+
assert Severity.try_get_value('MEDIUM') == 1
11+
assert Severity.try_get_value('HIGH') == 2
12+
assert Severity.try_get_value('CRITICAL') == 3
13+
14+
assert Severity.try_get_value('NON_EXISTENT') is None
15+
16+
17+
def test_get_member_weight() -> None:
18+
assert Severity.get_member_weight('INFO') == -1
19+
assert Severity.get_member_weight('LOW') == 0
20+
assert Severity.get_member_weight('MEDIUM') == 1
21+
assert Severity.get_member_weight('HIGH') == 2
22+
assert Severity.get_member_weight('CRITICAL') == 3
23+
24+
assert Severity.get_member_weight('NON_EXISTENT') == -2

0 commit comments

Comments
 (0)