From 70832f1e1e45d7ffee7c7e0c6ec9942683502355 Mon Sep 17 00:00:00 2001 From: ChanochShayner <57212002+ChanochShayner@users.noreply.github.com> Date: Sun, 20 Aug 2023 09:46:56 +0300 Subject: [PATCH] platform(sca): Filter IR FW upload results by supportedIrFw list (#5448) * filter IR FW by supportedIrFw list * Mypy + adding UT * cr fix * mypy & lint --- checkov/common/runners/runner_registry.py | 19 +++ checkov/main.py | 9 +- .../runner_registry/test_runner_registry.py | 150 ++++++++++++++++++ 3 files changed, 177 insertions(+), 1 deletion(-) diff --git a/checkov/common/runners/runner_registry.py b/checkov/common/runners/runner_registry.py index 621b6cb7854..739e762d7a7 100644 --- a/checkov/common/runners/runner_registry.py +++ b/checkov/common/runners/runner_registry.py @@ -38,6 +38,7 @@ from checkov.common.typing import _ExitCodeThresholds, _BaseRunner, _ScaExitCodeThresholds from checkov.common.util import data_structures_utils from checkov.common.util.banner import tool as tool_name +from checkov.common.util.data_structures_utils import pickle_deepcopy from checkov.common.util.json_utils import CustomJSONEncoder from checkov.common.util.secrets_omitter import SecretsOmitter from checkov.common.util.type_forcers import convert_csv_string_arg_to_list, force_list @@ -86,6 +87,7 @@ def __init__( self.runner_filter = runner_filter self.runners = list(runners) self.banner = banner + self.sca_supported_ir_report: Optional[Report] = None self.scan_reports: list[Report] = [] self.image_referencing_runners = self._get_image_referencing_runners() self.filter_runner_framework() @@ -210,8 +212,25 @@ def _merge_reports(self, reports: Iterable[Report | list[Report]]) -> list[Repor self._check_type_to_report_map[sub_report.check_type] = sub_report merged_reports.append(sub_report) + if self.should_add_sca_results_to_sca_supported_ir_report(sub_report, sub_reports): + if self.sca_supported_ir_report: + merge_reports(self.sca_supported_ir_report, sub_report) + else: + self.sca_supported_ir_report = pickle_deepcopy(sub_report) + return merged_reports + @staticmethod + def should_add_sca_results_to_sca_supported_ir_report(sub_report: Report, sub_reports: list[Report]) -> bool: + if sub_report.check_type == 'sca_image' and bc_integration.customer_run_config_response: + # The regular sca report + if len(sub_reports) == 1: + return True + # Dup report: first - regular iac, second - IR. we are checking that report fw is in the IR supported list. + if len(sub_reports) == 2 and sub_reports[0].check_type in bc_integration.customer_run_config_response.get('supportedIrFw', []): + return True + return False + def _handle_report(self, scan_report: Report, repo_root_for_plan_enrichment: list[str | Path] | None) -> None: integration_feature_registry.run_post_runner(scan_report) if metadata_integration.check_metadata: diff --git a/checkov/main.py b/checkov/main.py index 07c1caf88b9..1b7c392a12a 100755 --- a/checkov/main.py +++ b/checkov/main.py @@ -491,6 +491,7 @@ def run(self, banner: str = checkov_banner, tool: str = checkov_tool, source_typ excluded_paths=runner_filter.excluded_paths, included_paths=included_paths, git_configuration_folders=git_configuration_folders, + sca_supported_ir_report=runner_registry.sca_supported_ir_report, ) if self.config.create_baseline: @@ -659,6 +660,7 @@ def upload_results( excluded_paths: list[str] | None = None, included_paths: list[str] | None = None, git_configuration_folders: list[str] | None = None, + sca_supported_ir_report: Report | None = None, ) -> None: """Upload scan results and other relevant files""" @@ -670,7 +672,12 @@ def upload_results( ) if git_configuration_folders: bc_integration.persist_git_configuration(os.getcwd(), git_configuration_folders) - bc_integration.persist_scan_results(self.scan_reports) + if sca_supported_ir_report: + scan_reports_to_upload = [report for report in self.scan_reports if report.check_type != 'sca_image'] + scan_reports_to_upload.append(sca_supported_ir_report) + else: + scan_reports_to_upload = self.scan_reports + bc_integration.persist_scan_results(scan_reports_to_upload) bc_integration.persist_run_metadata(self.run_metadata) if bc_integration.enable_persist_graphs: bc_integration.persist_graphs(self.graphs, absolute_root_folder=absolute_root_folder) diff --git a/tests/common/runner_registry/test_runner_registry.py b/tests/common/runner_registry/test_runner_registry.py index 118eb00c08a..7e787b14b1d 100644 --- a/tests/common/runner_registry/test_runner_registry.py +++ b/tests/common/runner_registry/test_runner_registry.py @@ -450,6 +450,156 @@ def test_merge_reports_for_multi_frameworks_image_referencer_results(self): # then assert len(merged_reports[0].image_cached_results) == 2 + def test_merge_reports_sca_supported_ir_report(self): + from checkov.common.bridgecrew.platform_integration import bc_integration + bc_integration.customer_run_config_response = {'supportedIrFw': 'terraform'} + # given + runner_registry = RunnerRegistry(banner, RunnerFilter(), *DEFAULT_RUNNERS) + tf_report = Report(check_type=CheckType.TERRAFORM) + tf_ir_report = Report(check_type=CheckType.SCA_IMAGE) + tf_ir_report.image_cached_results = [ + { + "dockerImageName": "busybox", + "dockerFilePath": "/Users/arielk/dev/terragoat/terraform/aws/image-referencer.tf", + "dockerFileContent": "image: busybox", + "type": "Image", + "sourceId": "ariel-cli/terragoat", + "branch": "branch-name", + "sourceType": "cli", + "vulnerabilities": + [ + { + "cveId": "CVE-2022-28391", + "status": "open", + "severity": "high", + "packageName": "busybox", + "packageVersion": "1.34.1", + "link": "https://nvd.nist.gov/vuln/detail/CVE-2022-28391", + "cvss": 8.8, + "vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H", + "description": "BusyBox through 1.35.0 allows remote attackers to execute arbitrary code if netstat is used to print a DNS PTR record\\'s value to a VT compatible terminal. Alternatively, the attacker could choose to change the terminal\\'s colors.", + "riskFactors": + [ + "Attack complexity: low", + "Attack vector: network", + "High severity", + "Recent vulnerability", + "Remote execution" + ], + "publishedDate": "2022-04-03T21:15:00Z" + } + ], + "packages": + [], + "relatedResourceId": "/Users/arielk/dev/terragoat/terraform/aws/image-referencer.tf:aws_batch_job_definition.test1111" + } + ] + gha_report = Report(CheckType.GITHUB_ACTIONS) + gha_ir_report = Report(check_type=CheckType.SCA_IMAGE) + gha_ir_report.image_cached_results = [ + { + "dockerImageName": "nginx:stable-alpine-perl", + "dockerFilePath": "/.github/workflows/ci.yaml", + "dockerFileContent": "image: nginx:stable-alpine-perl", + "type": "Image", + "sourceId": "arielkru/ak19-pr-sce-test", + "branch": None, + "sourceType": "Github", + "vulnerabilities": + [ + { + "cveId": "CVE-2020-35538", + "status": "open", + "severity": "medium", + "packageName": "libjpeg-turbo", + "packageVersion": "2.1.3-r1", + "link": "https://nvd.nist.gov/vuln/detail/CVE-2020-35538", + "cvss": 5.5, + "vector": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H", + "description": "A crafted input file could cause a null pointer dereference in jcopy_sample_rows() when processed by libjpeg-turbo.", + "riskFactors": + [ + "Attack complexity: low", + "Medium severity" + ], + "publishedDate": "2022-08-31T16:15:00Z" + } + ], + "packages": + [ + { + "type": "os", + "name": "tzdata", + "version": "2022a-r0", + "licenses": + [ + "Public-Domain" + ] + } + ], + "relatedResourceId": "jobs.container-test-job", + } + ] + sca_report = Report(CheckType.SCA_IMAGE) + sca_report.image_cached_results = [ + { + "dockerImageName": "nginx:stable-alpine-perl2", + "dockerFilePath": "/.github/workflows/ci.yaml", + "dockerFileContent": "image: nginx:stable-alpine-perl", + "type": "Image", + "sourceId": "arielkru/ak19-pr-sce-test", + "branch": None, + "sourceType": "Github", + "vulnerabilities": + [ + { + "cveId": "CVE-2020-35538", + "status": "open", + "severity": "medium", + "packageName": "libjpeg-turbo", + "packageVersion": "2.1.3-r1", + "link": "https://nvd.nist.gov/vuln/detail/CVE-2020-35538", + "cvss": 5.5, + "vector": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H", + "description": "A crafted input file could cause a null pointer dereference in jcopy_sample_rows() when processed by libjpeg-turbo.", + "riskFactors": + [ + "Attack complexity: low", + "Medium severity" + ], + "publishedDate": "2022-08-31T16:15:00Z" + } + ], + "packages": + [ + { + "type": "os", + "name": "tzdata", + "version": "2022a-r0", + "licenses": + [ + "Public-Domain" + ] + } + ], + "relatedResourceId": "jobs.container-test-job", + } + ] + + reports = [ + [tf_report, tf_ir_report], + [gha_report, gha_ir_report], + sca_report + ] + + # when + merged_reports = runner_registry._merge_reports(reports=reports) + + # then + sca_report = [r for r in merged_reports if r.check_type == CheckType.SCA_IMAGE] + assert len(sca_report[0].image_cached_results) == 3 + assert len(runner_registry.sca_supported_ir_report.image_cached_results) == 2 + def test_non_compact_json_output(capsys): # given