From 57cc31909cb61a6a457a1b709bd432ff355cae3b Mon Sep 17 00:00:00 2001 From: John-Paul Dakran Date: Thu, 22 Sep 2022 08:15:57 -0700 Subject: [PATCH 1/2] Pass in context to analyze function so verify functions that use context dont get a None context --- detect_secrets/audit/common.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/detect_secrets/audit/common.py b/detect_secrets/audit/common.py index 7359fc419..0a1d6d587 100644 --- a/detect_secrets/audit/common.py +++ b/detect_secrets/audit/common.py @@ -19,6 +19,7 @@ from ..transformers import get_transformed_file from ..types import NamedIO from ..util.inject import call_function_with_arguments +from detect_secrets.util.code_snippet import get_code_snippet def get_baseline_from_file(filename: str) -> SecretsCollection: @@ -91,6 +92,7 @@ def get_raw_secrets_from_file( line_numbers = list(range(len(lines_to_scan))) for line_number, line in zip(line_numbers, lines_to_scan): + context = get_code_snippet(lines=lines_to_scan, line_number=line_number) identified_secrets = call_function_with_arguments( plugin.analyze_line, filename=secret.filename, @@ -100,6 +102,7 @@ def get_raw_secrets_from_file( # We enable eager search, because we *know* there's a secret here -- the baseline # flagged it after all. enable_eager_search=bool(secret.line_number), + context=context, ) for identified_secret in (identified_secrets or []): From 07e824452c2fee8f08c369030e5bb4604b56b810 Mon Sep 17 00:00:00 2001 From: John-Paul Dakran Date: Tue, 27 Sep 2022 07:43:25 -0700 Subject: [PATCH 2/2] Make snippet with all lines so verify can look around for information. Add unit test so we ensure we are calling a verify for audit unit tests --- detect_secrets/audit/common.py | 2 +- tests/audit/report_test.py | 40 ++++++++++++++++++++++++++++++++-- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/detect_secrets/audit/common.py b/detect_secrets/audit/common.py index 0a1d6d587..ca0bb2b76 100644 --- a/detect_secrets/audit/common.py +++ b/detect_secrets/audit/common.py @@ -92,7 +92,7 @@ def get_raw_secrets_from_file( line_numbers = list(range(len(lines_to_scan))) for line_number, line in zip(line_numbers, lines_to_scan): - context = get_code_snippet(lines=lines_to_scan, line_number=line_number) + context = get_code_snippet(lines=line_getter.lines, line_number=line_number + 1) identified_secrets = call_function_with_arguments( plugin.analyze_line, filename=secret.filename, diff --git a/tests/audit/report_test.py b/tests/audit/report_test.py index 653391607..a83e3585d 100644 --- a/tests/audit/report_test.py +++ b/tests/audit/report_test.py @@ -10,6 +10,7 @@ from detect_secrets.constants import VerifiedResult from detect_secrets.core import baseline from detect_secrets.core.secrets_collection import SecretsCollection +from detect_secrets.plugins.aws import AWSKeyDetector from detect_secrets.plugins.basic_auth import BasicAuthDetector from detect_secrets.plugins.jwt import JwtTokenDetector from detect_secrets.settings import transient_settings @@ -20,13 +21,14 @@ first_secret = 'value1' second_secret = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ' # noqa: E501 random_secret = ''.join(random.choice(string.ascii_letters) for _ in range(8)) +aws_secret = 'AKIAZZZZZZZZZZZZZZZZ' @pytest.mark.parametrize( 'class_to_print, expected_real, expected_false, expected_output', [ ( - None, 3, 1, + None, 4, 1, { 'results': [ { @@ -71,11 +73,21 @@ BasicAuthDetector.secret_type, ], }, + { + 'category': 'VERIFIED_TRUE', + 'lines': { + 1: 'aws_access_key = {}'.format(aws_secret), + }, + 'secrets': aws_secret, + 'types': [ + AWSKeyDetector.secret_type, + ], + }, ], }, ), ( - SecretClassToPrint.REAL_SECRET, 3, 0, + SecretClassToPrint.REAL_SECRET, 4, 0, { 'results': [ { @@ -109,6 +121,16 @@ JwtTokenDetector.secret_type, ], }, + { + 'category': 'VERIFIED_TRUE', + 'lines': { + 1: 'aws_access_key = {}'.format(aws_secret), + }, + 'secrets': aws_secret, + 'types': [ + AWSKeyDetector.secret_type, + ], + }, ], }, ), @@ -193,20 +215,33 @@ def baseline_file(): url = {url_format.format(second_secret)} example = {url_format.format(random_secret)} """)[1:] + third_content = textwrap.dedent(f""" + aws_access_key = {aws_secret} + """)[1:] with create_file_with_content(first_content) as first_file, \ create_file_with_content(second_content) as second_file, \ + create_file_with_content(third_content) as third_file, \ mock_named_temporary_file() as baseline_file, \ transient_settings({ 'plugins_used': [ {'name': 'BasicAuthDetector'}, {'name': 'JwtTokenDetector'}, + {'name': 'AWSKeyDetector'}, ], + 'filters_used': [ + { + 'path': + 'detect_secrets.filters.common.is_ignored_due_to_verification_policies', + 'min_level': 2, + }, + ], }): secrets = SecretsCollection() secrets.scan_file(first_file) secrets.scan_file(second_file) + secrets.scan_file(third_file) labels = { (first_file, BasicAuthDetector.secret_type, 1): True, (first_file, BasicAuthDetector.secret_type, 2): None, @@ -214,6 +249,7 @@ def baseline_file(): (second_file, JwtTokenDetector.secret_type, 1): True, (second_file, BasicAuthDetector.secret_type, 1): False, (second_file, BasicAuthDetector.secret_type, 2): False, + (third_file, AWSKeyDetector.secret_type, 1): True, } for item in secrets: _, secret = item