From 7254364a43bf591ef50e1ce68577d5be0ab70e63 Mon Sep 17 00:00:00 2001 From: Max Amelchenko Date: Wed, 23 Aug 2023 12:20:39 +0300 Subject: [PATCH 1/3] handle non iac secrets FP --- checkov/secrets/plugins/detector_utils.py | 7 ++++++- checkov/secrets/plugins/entropy_keyword_combinator.py | 5 ++++- tests/secrets/sanity/{non_iac_fp => iac_fp}/main.tf | 0 tests/secrets/sanity/{iac_fp => non_iac_fp}/a.py | 3 +++ 4 files changed, 13 insertions(+), 2 deletions(-) rename tests/secrets/sanity/{non_iac_fp => iac_fp}/main.tf (100%) rename tests/secrets/sanity/{iac_fp => non_iac_fp}/a.py (90%) diff --git a/checkov/secrets/plugins/detector_utils.py b/checkov/secrets/plugins/detector_utils.py index 0991948207b..29a3cec1841 100644 --- a/checkov/secrets/plugins/detector_utils.py +++ b/checkov/secrets/plugins/detector_utils.py @@ -174,7 +174,7 @@ } -def remove_fp_secrets_in_keys(detected_secrets: set[PotentialSecret], line: str) -> None: +def remove_fp_secrets_in_keys(detected_secrets: set[PotentialSecret], line: str, is_code_file: bool = False) -> None: formatted_line = line.replace('"', '').replace("'", '') secrets_to_remove = set() for detected_secret in detected_secrets: @@ -184,6 +184,11 @@ def remove_fp_secrets_in_keys(detected_secrets: set[PotentialSecret], line: str) # found a function name at the end of the line if detected_secret.secret_value and formatted_line and FUNCTION_CALL_AFTER_KEYWORD_REGEX.search(formatted_line): secrets_to_remove.add(detected_secret) + # secret value is substring of keywork + if is_code_file and FOLLOWED_BY_EQUAL_VALUE_KEYWORD_REGEX.search(formatted_line): + key, value = line.split("=", 1) + if detected_secret.secret_value in key and detected_secret.secret_value in value: + secrets_to_remove.add(detected_secret) detected_secrets -= secrets_to_remove diff --git a/checkov/secrets/plugins/entropy_keyword_combinator.py b/checkov/secrets/plugins/entropy_keyword_combinator.py index 569778e9a41..b542897b52d 100644 --- a/checkov/secrets/plugins/entropy_keyword_combinator.py +++ b/checkov/secrets/plugins/entropy_keyword_combinator.py @@ -209,7 +209,7 @@ def analyze_line( # return a possible secret, otherwise check with next parser return potential_secrets else: - return detect_secret( + detected_secrets = detect_secret( # If we found a keyword (i.e. db_pass = ), lower the threshold to the iac threshold scanners=self.high_entropy_scanners if not keyword_on_key else self.entropy_scanners_non_iac_with_keyword, filename=filename, @@ -217,6 +217,9 @@ def analyze_line( line_number=line_number, kwargs=kwargs ) + if detected_secrets: + remove_fp_secrets_in_keys(detected_secrets, line, True) + return detected_secrets return set() diff --git a/tests/secrets/sanity/non_iac_fp/main.tf b/tests/secrets/sanity/iac_fp/main.tf similarity index 100% rename from tests/secrets/sanity/non_iac_fp/main.tf rename to tests/secrets/sanity/iac_fp/main.tf diff --git a/tests/secrets/sanity/iac_fp/a.py b/tests/secrets/sanity/non_iac_fp/a.py similarity index 90% rename from tests/secrets/sanity/iac_fp/a.py rename to tests/secrets/sanity/non_iac_fp/a.py index b27dad91547..52675cca7a0 100644 --- a/tests/secrets/sanity/iac_fp/a.py +++ b/tests/secrets/sanity/non_iac_fp/a.py @@ -3,6 +3,9 @@ def a(): mock_url = mock_bc_integration.bc_api_url + "/api/v1/vulnerabilities/scan-results/2e97f5afea42664309f492a1e2083b43479c2936" + PASSWORD = "PASSWORD" + STATUS_ERROR_PASSWORD_FETCH = "ERROR_PASSWORD_FETCH" + return "Properties/LogPublishingOptions/AUDIT_LOGS/Enabled" metadata_options['HttpTokens'] == "required" From 34ab54ba4219050733f21a05e4ba6958c628347d Mon Sep 17 00:00:00 2001 From: Max Amelchenko Date: Wed, 23 Aug 2023 12:31:02 +0300 Subject: [PATCH 2/3] fix mypy issue --- checkov/secrets/plugins/detector_utils.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/checkov/secrets/plugins/detector_utils.py b/checkov/secrets/plugins/detector_utils.py index 29a3cec1841..7d53f3e807c 100644 --- a/checkov/secrets/plugins/detector_utils.py +++ b/checkov/secrets/plugins/detector_utils.py @@ -178,17 +178,18 @@ def remove_fp_secrets_in_keys(detected_secrets: set[PotentialSecret], line: str, formatted_line = line.replace('"', '').replace("'", '') secrets_to_remove = set() for detected_secret in detected_secrets: - # Found keyword prefix as potential secret - if detected_secret.secret_value and formatted_line.startswith(detected_secret.secret_value): - secrets_to_remove.add(detected_secret) - # found a function name at the end of the line - if detected_secret.secret_value and formatted_line and FUNCTION_CALL_AFTER_KEYWORD_REGEX.search(formatted_line): - secrets_to_remove.add(detected_secret) - # secret value is substring of keywork - if is_code_file and FOLLOWED_BY_EQUAL_VALUE_KEYWORD_REGEX.search(formatted_line): - key, value = line.split("=", 1) - if detected_secret.secret_value in key and detected_secret.secret_value in value: + if detected_secret.secret_value: + # Found keyword prefix as potential secret + if formatted_line.startswith(detected_secret.secret_value): secrets_to_remove.add(detected_secret) + # found a function name at the end of the line + if formatted_line and FUNCTION_CALL_AFTER_KEYWORD_REGEX.search(formatted_line): + secrets_to_remove.add(detected_secret) + # secret value is substring of keywork + if is_code_file and FOLLOWED_BY_EQUAL_VALUE_KEYWORD_REGEX.search(formatted_line): + key, value = line.split("=", 1) + if detected_secret.secret_value in key and detected_secret.secret_value in value: + secrets_to_remove.add(detected_secret) detected_secrets -= secrets_to_remove From 6033ecca8b8bbd7bd0d902308d46571aab594629 Mon Sep 17 00:00:00 2001 From: Max Amelchenko Date: Wed, 23 Aug 2023 14:21:22 +0300 Subject: [PATCH 3/3] fix according to comments --- checkov/secrets/plugins/detector_utils.py | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/checkov/secrets/plugins/detector_utils.py b/checkov/secrets/plugins/detector_utils.py index 7d53f3e807c..3ca1feb714f 100644 --- a/checkov/secrets/plugins/detector_utils.py +++ b/checkov/secrets/plugins/detector_utils.py @@ -178,18 +178,19 @@ def remove_fp_secrets_in_keys(detected_secrets: set[PotentialSecret], line: str, formatted_line = line.replace('"', '').replace("'", '') secrets_to_remove = set() for detected_secret in detected_secrets: - if detected_secret.secret_value: - # Found keyword prefix as potential secret - if formatted_line.startswith(detected_secret.secret_value): + if not detected_secret.secret_value: + continue + # Found keyword prefix as potential secret + if formatted_line.startswith(detected_secret.secret_value): + secrets_to_remove.add(detected_secret) + # found a function name at the end of the line + if formatted_line and FUNCTION_CALL_AFTER_KEYWORD_REGEX.search(formatted_line): + secrets_to_remove.add(detected_secret) + # secret value is substring of keywork + if is_code_file and FOLLOWED_BY_EQUAL_VALUE_KEYWORD_REGEX.search(formatted_line): + key, value = line.split("=", 1) + if detected_secret.secret_value in key and detected_secret.secret_value in value: secrets_to_remove.add(detected_secret) - # found a function name at the end of the line - if formatted_line and FUNCTION_CALL_AFTER_KEYWORD_REGEX.search(formatted_line): - secrets_to_remove.add(detected_secret) - # secret value is substring of keywork - if is_code_file and FOLLOWED_BY_EQUAL_VALUE_KEYWORD_REGEX.search(formatted_line): - key, value = line.split("=", 1) - if detected_secret.secret_value in key and detected_secret.secret_value in value: - secrets_to_remove.add(detected_secret) detected_secrets -= secrets_to_remove