Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ The Cycode CLI application offers several types of scans so that you can choose
| `--client-id TEXT` | Specify a Cycode client ID for this specific scan execution |
| `--show-secret BOOLEAN` | Show secrets in plain text. See [Show/Hide Secrets](#showhide-secrets) section for more details. |
| `--soft-fail BOOLEAN` | Run scan without failing, always return a non-error status code. See [Soft Fail](#soft-fail) section for more details. |
| `--severity-threshold [INFO\|LOW\|MEDIUM\|HIGH\|CRITICAL]` | Show only violations at the specified level or higher (supported for the SCA scan type only). |
| `--severity-threshold [INFO\|LOW\|MEDIUM\|HIGH\|CRITICAL]` | Show only violations at the specified level or higher. |
| `--sca-scan` | Specify the SCA scan you wish to execute (`package-vulnerabilities`/`license-compliance`). The default is both |
| `--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). |
| `--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 |
Expand Down
21 changes: 14 additions & 7 deletions cycode/cli/commands/scan/code_scanner.py
Original file line number Diff line number Diff line change
Expand Up @@ -713,20 +713,26 @@ def exclude_irrelevant_detections(
) -> List[Detection]:
relevant_detections = _exclude_detections_by_exclusions_configuration(detections, scan_type)
relevant_detections = _exclude_detections_by_scan_type(relevant_detections, scan_type, command_scan_type)
return _exclude_detections_by_severity(relevant_detections, scan_type, severity_threshold)
return _exclude_detections_by_severity(relevant_detections, severity_threshold)


def _exclude_detections_by_severity(
detections: List[Detection], scan_type: str, severity_threshold: str
) -> List[Detection]:
if scan_type != consts.SCA_SCAN_TYPE or severity_threshold is None:
def _exclude_detections_by_severity(detections: List[Detection], severity_threshold: str) -> List[Detection]:
if severity_threshold is None:
return detections

relevant_detections = []
for detection in detections:
severity = detection.detection_details.get('advisory_severity')
if not severity:
severity = detection.severity

if _does_severity_match_severity_threshold(severity, severity_threshold):
relevant_detections.append(detection)
else:
logger.debug(
'Going to ignore violations because they are below the severity threshold, %s',
{'severity': severity, 'severity_threshold': severity_threshold},
)

return relevant_detections

Expand Down Expand Up @@ -861,10 +867,11 @@ def _generate_unique_id() -> UUID:

def _does_severity_match_severity_threshold(severity: str, severity_threshold: str) -> bool:
detection_severity_value = Severity.try_get_value(severity)
if detection_severity_value is None:
severity_threshold_value = Severity.try_get_value(severity_threshold)
if detection_severity_value is None or severity_threshold_value is None:
return True

return detection_severity_value >= Severity.try_get_value(severity_threshold)
return detection_severity_value >= severity_threshold_value


def _get_scan_result(
Expand Down
2 changes: 1 addition & 1 deletion cycode/cli/commands/scan/scan_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
@click.option(
'--severity-threshold',
default=None,
help='Show violations only for the specified level or higher (supported for SCA scan types only).',
help='Show violations only for the specified level or higher.',
type=click.Choice([e.name for e in Severity]),
required=False,
)
Expand Down
1 change: 1 addition & 0 deletions cycode/cli/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class Severity(Enum):

@staticmethod
def try_get_value(name: str) -> any:
name = name.upper()
if name not in Severity.__members__:
return None

Expand Down
22 changes: 22 additions & 0 deletions tests/cli/commands/scan/test_code_scanner.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os

from cycode.cli import consts
from cycode.cli.commands.scan.code_scanner import _does_severity_match_severity_threshold
from cycode.cli.files_collector.excluder import _is_file_relevant_for_sca_scan
from cycode.cli.files_collector.path_documents import _generate_document
from cycode.cli.models import Document
Expand Down Expand Up @@ -72,3 +73,24 @@ def test_generate_document() -> None:
assert isinstance(generated_tfplan_document, Document)
assert generated_tfplan_document.path.endswith('.tf')
assert generated_tfplan_document.is_git_diff_format == is_git_diff


def test_does_severity_match_severity_threshold() -> None:
assert _does_severity_match_severity_threshold('INFO', 'LOW') is False

assert _does_severity_match_severity_threshold('LOW', 'LOW') is True
assert _does_severity_match_severity_threshold('LOW', 'MEDIUM') is False

assert _does_severity_match_severity_threshold('MEDIUM', 'LOW') is True
assert _does_severity_match_severity_threshold('MEDIUM', 'MEDIUM') is True
assert _does_severity_match_severity_threshold('MEDIUM', 'HIGH') is False

assert _does_severity_match_severity_threshold('HIGH', 'MEDIUM') is True
assert _does_severity_match_severity_threshold('HIGH', 'HIGH') is True
assert _does_severity_match_severity_threshold('HIGH', 'CRITICAL') is False

assert _does_severity_match_severity_threshold('CRITICAL', 'HIGH') is True
assert _does_severity_match_severity_threshold('CRITICAL', 'CRITICAL') is True

assert _does_severity_match_severity_threshold('NON_EXISTENT', 'LOW') is True
assert _does_severity_match_severity_threshold('LOW', 'NON_EXISTENT') is True
Empty file added tests/cli/models/__init__.py
Empty file.
24 changes: 24 additions & 0 deletions tests/cli/models/test_severity.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from cycode.cli.models import Severity


def test_try_get_value() -> None:
assert Severity.try_get_value('info') == -1
assert Severity.try_get_value('iNfO') == -1

assert Severity.try_get_value('INFO') == -1
assert Severity.try_get_value('LOW') == 0
assert Severity.try_get_value('MEDIUM') == 1
assert Severity.try_get_value('HIGH') == 2
assert Severity.try_get_value('CRITICAL') == 3

assert Severity.try_get_value('NON_EXISTENT') is None


def test_get_member_weight() -> None:
assert Severity.get_member_weight('INFO') == -1
assert Severity.get_member_weight('LOW') == 0
assert Severity.get_member_weight('MEDIUM') == 1
assert Severity.get_member_weight('HIGH') == 2
assert Severity.get_member_weight('CRITICAL') == 3

assert Severity.get_member_weight('NON_EXISTENT') == -2
Loading