From 8ef0b6341e03e2cce6fde07fbe32d3bd50bea565 Mon Sep 17 00:00:00 2001 From: Mike Urbanski Date: Wed, 25 Oct 2023 07:25:54 -0500 Subject: [PATCH 1/3] platform(general): Add SAST enforcement rules and check severity thresholds (#5684) * pass check and skip check severity thresholds to sast core * add test for get_check_thresholds * fix mypy issues * fix mypy issues --- checkov/common/bridgecrew/severities.py | 3 ++ checkov/sast/engines/prisma_engine.py | 32 ++++++++++++++- checkov/sast/prisma_models/library_input.py | 4 ++ tests/sast/test_runner.py | 44 +++++++++++++++++++++ 4 files changed, 81 insertions(+), 2 deletions(-) diff --git a/checkov/common/bridgecrew/severities.py b/checkov/common/bridgecrew/severities.py index 9e937bf5d42..f78dadb9a99 100644 --- a/checkov/common/bridgecrew/severities.py +++ b/checkov/common/bridgecrew/severities.py @@ -12,6 +12,9 @@ def __init__(self, name: str, level: int) -> None: def __repr__(self) -> str: return self.name + def __str__(self) -> str: + return self.name + @dataclass class BcSeverities: diff --git a/checkov/sast/engines/prisma_engine.py b/checkov/sast/engines/prisma_engine.py index 7c6713bee7b..66823fcfb95 100644 --- a/checkov/sast/engines/prisma_engine.py +++ b/checkov/sast/engines/prisma_engine.py @@ -7,7 +7,7 @@ import re import stat from pathlib import Path -from typing import Optional, List, Set, Union, Dict, Any +from typing import Optional, List, Set, Union, Dict, Any, Tuple, cast from cachetools import cached, TTLCache from pydantic import ValidationError @@ -15,7 +15,7 @@ from checkov.common.bridgecrew.check_type import CheckType from checkov.common.bridgecrew.platform_integration import bc_integration from checkov.common.bridgecrew.platform_key import bridgecrew_dir -from checkov.common.bridgecrew.severities import get_severity +from checkov.common.bridgecrew.severities import get_severity, Severity, Severities, BcSeverities from checkov.common.models.enums import CheckResult from checkov.common.output.report import Report from checkov.common.sca.reachability.sast_contract.data_fetcher_sast_lib import SastReachabilityDataFetcher @@ -43,6 +43,24 @@ def __init__(self) -> None: self.prisma_sast_dir_path = Path(bridgecrew_dir) / "sast" self.sast_platform_base_path = "api/v1/sast" + def get_check_thresholds(self, registry: Registry) -> Tuple[Severity, Severity]: + """ + Returns a tuple of check threshold and skip check threshold.. + + If a severity was specified in --check and / or --skip-check, then return a tuple of those values (these override enforcement rules). + Else if enforcement rules are enabled, return a tuple of the enforcement rule's SAST soft fail threshold and NONE. + Else return a tuple of NONE, NONE + """ + none = Severities[BcSeverities.NONE] + + check_threshold: Optional[Severity] = registry.runner_filter.check_threshold # type:ignore[union-attr] # not null + skip_check_threshold: Optional[Severity] = registry.runner_filter.skip_check_threshold # type:ignore[union-attr] # not null + enforcement_threshold: Optional[Severity] = cast(Severity, registry.runner_filter.enforcement_rule_configs[self.check_type]) if registry.runner_filter.use_enforcement_rules else None # type:ignore[union-attr] # not null + + return (check_threshold or none, skip_check_threshold or none) if (check_threshold or skip_check_threshold) else \ + (enforcement_threshold, none) if enforcement_threshold else \ + (none, none) + def get_reports(self, targets: List[str], registry: Registry, languages: Set[SastLanguages]) -> List[Report]: if not bc_integration.bc_api_key: logging.info("The --bc-api-key flag needs to be set to run SAST Prisma Cloud scanning") @@ -58,12 +76,16 @@ def get_reports(self, targets: List[str], registry: Registry, languages: Set[Sas self.lib_path = str(prisma_lib_path) + check_threshold, skip_check_threshold = self.get_check_thresholds(registry) + library_input: LibraryInput = { 'languages': languages, 'source_codes': targets, 'policies': registry.checks_dirs_path, 'checks': registry.runner_filter.checks if registry.runner_filter else [], 'skip_checks': registry.runner_filter.skip_checks if registry.runner_filter else [], + 'check_threshold': check_threshold, + 'skip_check_threshold': skip_check_threshold, 'skip_path': registry.runner_filter.excluded_paths if registry.runner_filter else [], 'report_imports': registry.runner_filter.report_sast_imports if registry.runner_filter else False, 'remove_default_policies': registry.runner_filter.remove_default_sast_policies if registry.runner_filter else False, @@ -164,6 +186,8 @@ def run_go_library(self, languages: Set[SastLanguages], checks: List[str], skip_checks: List[str], skip_path: List[str], + check_threshold: Severity, + skip_check_threshold: Severity, list_policies: bool = False, report_imports: bool = True, report_reachability: bool = False, @@ -190,6 +214,8 @@ def run_go_library(self, languages: Set[SastLanguages], "checks": checks, "skip_checks": skip_checks, "skip_path": skip_path, + "check_threshold": str(check_threshold), + "skip_check_threshold": str(skip_check_threshold), "list_policies": list_policies, "report_imports": report_imports, "remove_default_policies": remove_default_policies, @@ -338,6 +364,8 @@ def get_policies(self, languages: Set[SastLanguages]) -> SastPolicies: 'policies': [], 'checks': [], 'skip_checks': [], + 'check_threshold': Severities[BcSeverities.NONE], + 'skip_check_threshold': Severities[BcSeverities.NONE], 'skip_path': [], 'report_imports': False, 'report_reachability': False diff --git a/checkov/sast/prisma_models/library_input.py b/checkov/sast/prisma_models/library_input.py index fd5ef77186f..e28c9a1533b 100644 --- a/checkov/sast/prisma_models/library_input.py +++ b/checkov/sast/prisma_models/library_input.py @@ -1,4 +1,6 @@ from typing import Set, List + +from checkov.common.bridgecrew.severities import Severity from checkov.sast.consts import SastLanguages import sys if sys.version_info < (3, 11): @@ -14,6 +16,8 @@ class LibraryInput(TypedDict): checks: List[str] skip_checks: List[str] skip_path: List[str] + check_threshold: Severity + skip_check_threshold: Severity list_policies: NotRequired[bool] report_imports: bool remove_default_policies: NotRequired[bool] diff --git a/tests/sast/test_runner.py b/tests/sast/test_runner.py index 3549aadcff2..6d0d91e3aa1 100644 --- a/tests/sast/test_runner.py +++ b/tests/sast/test_runner.py @@ -2,7 +2,10 @@ from checkov.common.bridgecrew.check_type import CheckType from checkov.common.bridgecrew.platform_integration import bc_integration +from checkov.common.bridgecrew.severities import Severities, BcSeverities from checkov.common.models.enums import CheckResult +from checkov.sast.checks_infra.base_registry import Registry +from checkov.sast.engines.prisma_engine import PrismaEngine from checkov.sast.runner import Runner from checkov.runner_filter import RunnerFilter import pathlib @@ -97,3 +100,44 @@ def test_sast_prisma_runner(mocker): bc_integration.bc_api_key = temp assert len(reports) == 0 + + +def test_get_check_thresholds(): + prisma_engine = PrismaEngine() + registry = Registry('') + runner_filter = RunnerFilter() + registry.runner_filter = runner_filter + + none = Severities[BcSeverities.NONE] + medium = Severities[BcSeverities.MEDIUM] + high = Severities[BcSeverities.HIGH] + + # test plain thresholds specified using --check and --skip-check, no enforcement rules + assert prisma_engine.get_check_thresholds(registry) == (none, none) + + runner_filter.check_threshold = medium + assert prisma_engine.get_check_thresholds(registry) == (medium, none) + + runner_filter.skip_check_threshold = medium + assert prisma_engine.get_check_thresholds(registry) == (medium, medium) + + runner_filter.check_threshold = None + assert prisma_engine.get_check_thresholds(registry) == (none, medium) + + # apply enforcement rules + runner_filter.skip_check_threshold = None + runner_filter.use_enforcement_rules = True + runner_filter.enforcement_rule_configs = { + CheckType.SAST: high + } + assert prisma_engine.get_check_thresholds(registry) == (high, none) + + # but --check and --skip-check with severities overrides enforcement rules + runner_filter.check_threshold = medium + assert prisma_engine.get_check_thresholds(registry) == (medium, none) + + runner_filter.skip_check_threshold = medium + assert prisma_engine.get_check_thresholds(registry) == (medium, medium) + + runner_filter.check_threshold = None + assert prisma_engine.get_check_thresholds(registry) == (none, medium) From 8cc2d600896bcf8bedeae0043c379c49753d9fba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anton=20Gr=C3=BCbel?= Date: Wed, 25 Oct 2023 14:26:14 +0200 Subject: [PATCH 2/3] fix(secrets): fix secret FP of client_secret_setting_name (#5679) fix secret FP of client_secret_setting_name --- checkov/secrets/plugins/detector_utils.py | 8 +++++++- tests/secrets/sanity/iac_fp/main.tf | 4 +++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/checkov/secrets/plugins/detector_utils.py b/checkov/secrets/plugins/detector_utils.py index 3ca1feb714f..0c632869444 100644 --- a/checkov/secrets/plugins/detector_utils.py +++ b/checkov/secrets/plugins/detector_utils.py @@ -108,7 +108,13 @@ flags=re.IGNORECASE, ) -ALLOW_LIST = ('secretsmanager', "secretName", "secret_name", "creation_token") # can add more keys like that +ALLOW_LIST = ( # can add more keys like that + 'secretsmanager', + "secretName", + "secret_name", + "creation_token", + "client_secret_setting_name", +) ALLOW_LIST_REGEX = r'|'.join(ALLOW_LIST) # Support for suffix of function name i.e "secretsmanager:GetSecretValue" CAMEL_CASE_NAMES = r'[A-Z]([A-Z0-9]*[a-z][a-z0-9]*[A-Z]|[a-z0-9]*[A-Z][A-Z0-9]*[a-z])[A-Za-z0-9]*' diff --git a/tests/secrets/sanity/iac_fp/main.tf b/tests/secrets/sanity/iac_fp/main.tf index a463a10e301..c443f0fd948 100644 --- a/tests/secrets/sanity/iac_fp/main.tf +++ b/tests/secrets/sanity/iac_fp/main.tf @@ -1,3 +1,5 @@ secret_name = "example_secret_name" -creation_token = "my-product" \ No newline at end of file +creation_token = "my-product" + +client_secret_setting_name = "MICROSOFT_PROVIDER_AUTHENTICATION_SECRET" From 2c8fcc7d1d597e7ea75466aa9d13de66f62cfa2e Mon Sep 17 00:00:00 2001 From: Mike Urbanski Date: Wed, 25 Oct 2023 07:25:54 -0500 Subject: [PATCH 3/3] platform(general): Add SAST enforcement rules and check severity thresholds (#5684) * pass check and skip check severity thresholds to sast core * add test for get_check_thresholds * fix mypy issues * fix mypy issues --- checkov/version.py | 2 +- kubernetes/requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/checkov/version.py b/checkov/version.py index 0fe485cb49f..996ccf8b135 100644 --- a/checkov/version.py +++ b/checkov/version.py @@ -1 +1 @@ -version = '3.0.5' +version = '3.0.6' diff --git a/kubernetes/requirements.txt b/kubernetes/requirements.txt index b048f19538f..855dc787923 100644 --- a/kubernetes/requirements.txt +++ b/kubernetes/requirements.txt @@ -1 +1 @@ -checkov==3.0.5 +checkov==3.0.6