From 4857c703ab868850fde08eaf0b621d5b9693c850 Mon Sep 17 00:00:00 2001 From: naorda Date: Tue, 21 May 2024 21:06:46 +0300 Subject: [PATCH] feat(secrets): entropy limit as env variable (#6332) * entropy limit as env variable * entropy limit as env variable * remove or --- .../plugins/entropy_keyword_combinator.py | 19 +++++++++++----- checkov/secrets/runner.py | 22 ++++++++++++++----- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/checkov/secrets/plugins/entropy_keyword_combinator.py b/checkov/secrets/plugins/entropy_keyword_combinator.py index b542897b52d..02aeb568095 100644 --- a/checkov/secrets/plugins/entropy_keyword_combinator.py +++ b/checkov/secrets/plugins/entropy_keyword_combinator.py @@ -1,6 +1,7 @@ from __future__ import annotations import re +import os from typing import Generator, Set, Tuple from typing import Any from typing import TYPE_CHECKING @@ -29,7 +30,7 @@ MAX_LINE_LENGTH = 10000 MAX_KEYWORD_LIMIT = 500 -ENTROPY_KEYWORD_COMBINATOR_LIMIT = 3 +ENTROPY_KEYWORD_COMBINATOR_LIMIT = float(os.getenv('CHECKOV_ENTROPY_KEYWORD_LIMIT', '3')) ENTROPY_KEYWORD_LIMIT = 4.8 DENY_LIST_REGEX = r'|'.join(DENYLIST) @@ -118,10 +119,18 @@ class EntropyKeywordCombinator(BasePlugin): secret_type = "" # nosec # noqa: CCE003 # a static attribute - def __init__(self, limit: float = ENTROPY_KEYWORD_LIMIT, max_line_length: int = MAX_LINE_LENGTH) -> None: - iac_limit = ENTROPY_KEYWORD_COMBINATOR_LIMIT - self.high_entropy_scanners_iac = (Base64HighEntropyString(limit=iac_limit), HexHighEntropyString(limit=iac_limit)) - self.entropy_scanners_non_iac_with_keyword = (Base64HighEntropyString(limit=iac_limit + 0.3), HexHighEntropyString(limit=iac_limit + 0.3)) + def __init__(self, limit: float = ENTROPY_KEYWORD_LIMIT, max_line_length: int = MAX_LINE_LENGTH, + entropy_limit: float = ENTROPY_KEYWORD_COMBINATOR_LIMIT) -> None: + self.entropy_limit = entropy_limit + self.high_entropy_scanners_iac = ( + Base64HighEntropyString( + limit=entropy_limit), HexHighEntropyString( + limit=entropy_limit)) + self.entropy_scanners_non_iac_with_keyword = ( + Base64HighEntropyString( + limit=entropy_limit + 0.3), + HexHighEntropyString( + limit=entropy_limit + 0.3)) self.high_entropy_scanners = (Base64HighEntropyString(limit=limit), HexHighEntropyString(limit=limit)) self.keyword_scanner = KeywordDetector() self.max_line_length = max_line_length diff --git a/checkov/secrets/runner.py b/checkov/secrets/runner.py index 44d1e87b72b..b7f681116bb 100644 --- a/checkov/secrets/runner.py +++ b/checkov/secrets/runner.py @@ -84,10 +84,15 @@ class Runner(BaseRunner[None, None, None]): check_type = CheckType.SECRETS # noqa: CCE003 # a static attribute - def __init__(self, file_extensions: Iterable[str] | None = None, file_names: Iterable[str] | None = None): + def __init__( + self, + file_extensions: Iterable[str] | None = None, + file_names: Iterable[str] | None = None, + entropy_limit: Optional[int] = None): super().__init__(file_extensions, file_names) self.secrets_coordinator = SecretsCoordinator() self.history_secret_store = GitHistorySecretStore() + self.entropy_limit = entropy_limit or float(os.getenv('CHECKOV_ENTROPY_KEYWORD_LIMIT', '3')) def set_history_secret_store(self, value: Dict[str, List[EnrichedPotentialSecret]]) -> None: self.history_secret_store.secrets_by_file_value_type = value @@ -121,7 +126,8 @@ def run( {'name': 'SquareOAuthDetector'}, {'name': 'StripeDetector'}, {'name': 'TwilioKeyDetector'}, - {'name': 'EntropyKeywordCombinator', 'path': f'file://{current_dir}/plugins/entropy_keyword_combinator.py'} + {'name': 'EntropyKeywordCombinator', 'path': f'file://{current_dir}/plugins/entropy_keyword_combinator.py', + 'entropy_limit': self.entropy_limit} ] # load runnable plugins @@ -138,7 +144,8 @@ def run( policies_list = customer_run_config.get('secretsPolicies', []) suppressions = customer_run_config.get('suppressions', []) if suppressions: - secret_suppressions_id = [suppression['policyId'] for suppression in suppressions if suppression['suppressionType'] == 'SecretsPolicy'] + secret_suppressions_id = [suppression['policyId'] + for suppression in suppressions if suppression['suppressionType'] == 'SecretsPolicy'] if policies_list: runnable_plugins: dict[str, str] = get_runnable_plugins(policies_list) logging.info(f"Found {len(runnable_plugins)} runnable plugins") @@ -188,8 +195,10 @@ def run( if enable_secret_scan_all_files: # 'excluded_paths' shouldn't include the static paths from 'EXCLUDED_PATHS' # they are separately referenced inside the 'filter_excluded_paths' function - filter_excluded_paths(root_dir=root, names=d_names, excluded_paths=runner_filter.excluded_paths) - filter_excluded_paths(root_dir=root, names=f_names, excluded_paths=runner_filter.excluded_paths) + filter_excluded_paths( + root_dir=root, names=d_names, excluded_paths=runner_filter.excluded_paths) + filter_excluded_paths( + root_dir=root, names=f_names, excluded_paths=runner_filter.excluded_paths) else: filter_ignored_paths(root, d_names, excluded_paths) filter_ignored_paths(root, f_names, excluded_paths) @@ -423,7 +432,8 @@ def verify_secrets(self, report: Report, enriched_secrets_s3_path: str) -> Verif validate_secrets_tenant_config = None if bc_integration.customer_run_config_response is not None: - validate_secrets_tenant_config = bc_integration.customer_run_config_response.get('tenantConfig', {}).get('secretsValidate') + validate_secrets_tenant_config = bc_integration.customer_run_config_response.get( + 'tenantConfig', {}).get('secretsValidate') if validate_secrets_tenant_config is None and not convert_str_to_bool(os.getenv("CKV_VALIDATE_SECRETS", False)): logging.debug('Secrets verification is off, enable it via code configuration screen')