diff --git a/prowler/providers/aws/services/awslambda/awslambda_function_no_secrets_in_code/awslambda_function_no_secrets_in_code.py b/prowler/providers/aws/services/awslambda/awslambda_function_no_secrets_in_code/awslambda_function_no_secrets_in_code.py index 3a4362c1..3d743853 100644 --- a/prowler/providers/aws/services/awslambda/awslambda_function_no_secrets_in_code/awslambda_function_no_secrets_in_code.py +++ b/prowler/providers/aws/services/awslambda/awslambda_function_no_secrets_in_code/awslambda_function_no_secrets_in_code.py @@ -26,15 +26,40 @@ class awslambda_function_no_secrets_in_code(Check): function.code.code_zip.extractall(tmp_dir_name) # List all files files_in_zip = next(os.walk(tmp_dir_name))[2] + secrets_findings = [] for file in files_in_zip: secrets = SecretsCollection() with default_settings(): secrets.scan_file(f"{tmp_dir_name}/{file}") + detect_secrets_output = secrets.json() + if detect_secrets_output: + for ( + file_name + ) in ( + detect_secrets_output.keys() + ): # Appears that only 1 file is being scanned at a time, so could rework this + output_file_name = file_name.replace( + f"{tmp_dir_name}/", "" + ) + secrets_string = ", ".join( + [ + f"{secret['type']} on line {secret['line_number']}" + for secret in detect_secrets_output[file_name] + ] + ) + secrets_findings.append( + f"{output_file_name}: {secrets_string}" + ) - if secrets.json(): - report.status = "FAIL" - report.status_extended = f"Potential secret found in Lambda function {function.name} code" - break + if secrets_findings: + final_output_string = "; ".join(secrets_findings) + report.status = "FAIL" + # report.status_extended = f"Potential {'secrets' if len(secrets_findings)>1 else 'secret'} found in Lambda function {function.name} code. {final_output_string}" + if len(secrets_findings) > 1: + report.status_extended = f"Potential secrets found in Lambda function {function.name} code -> {final_output_string}" + else: + report.status_extended = f"Potential secret found in Lambda function {function.name} code -> {final_output_string}" + # break // Don't break as there may be additional findings findings.append(report) diff --git a/prowler/providers/aws/services/awslambda/awslambda_function_no_secrets_in_variables/awslambda_function_no_secrets_in_variables.py b/prowler/providers/aws/services/awslambda/awslambda_function_no_secrets_in_variables/awslambda_function_no_secrets_in_variables.py index 0fa7ecee..0bad2a4e 100644 --- a/prowler/providers/aws/services/awslambda/awslambda_function_no_secrets_in_variables/awslambda_function_no_secrets_in_variables.py +++ b/prowler/providers/aws/services/awslambda/awslambda_function_no_secrets_in_variables/awslambda_function_no_secrets_in_variables.py @@ -27,7 +27,8 @@ class awslambda_function_no_secrets_in_variables(Check): temp_env_data_file = tempfile.NamedTemporaryFile(delete=False) temp_env_data_file.write( bytes( - json.dumps(function.environment), encoding="raw_unicode_escape" + json.dumps(function.environment, indent=2), + encoding="raw_unicode_escape", ) ) temp_env_data_file.close() @@ -35,9 +36,17 @@ class awslambda_function_no_secrets_in_variables(Check): with default_settings(): secrets.scan_file(temp_env_data_file.name) - if secrets.json(): + detect_secrets_output = secrets.json() + if detect_secrets_output: + environment_variable_names = list(function.environment.keys()) + secrets_string = ", ".join( + [ + f"{secret['type']} in variable {environment_variable_names[int(secret['line_number'])-2]}" + for secret in detect_secrets_output[temp_env_data_file.name] + ] + ) report.status = "FAIL" - report.status_extended = f"Potential secret found in Lambda function {function.name} variables" + report.status_extended = f"Potential secret found in Lambda function {function.name} variables -> {secrets_string}" os.remove(temp_env_data_file.name) diff --git a/prowler/providers/aws/services/ecs/ecs_task_definitions_no_environment_secrets/ecs_task_definitions_no_environment_secrets.py b/prowler/providers/aws/services/ecs/ecs_task_definitions_no_environment_secrets/ecs_task_definitions_no_environment_secrets.py index 3dcc96e5..908dd520 100644 --- a/prowler/providers/aws/services/ecs/ecs_task_definitions_no_environment_secrets/ecs_task_definitions_no_environment_secrets.py +++ b/prowler/providers/aws/services/ecs/ecs_task_definitions_no_environment_secrets/ecs_task_definitions_no_environment_secrets.py @@ -26,7 +26,7 @@ class ecs_task_definitions_no_environment_secrets(Check): temp_env_data_file = tempfile.NamedTemporaryFile(delete=False) - env_data = dumps(dump_env_vars) + env_data = dumps(dump_env_vars, indent=2) temp_env_data_file.write(bytes(env_data, encoding="raw_unicode_escape")) temp_env_data_file.close() @@ -34,9 +34,16 @@ class ecs_task_definitions_no_environment_secrets(Check): with default_settings(): secrets.scan_file(temp_env_data_file.name) - if secrets.json(): + detect_secrets_output = secrets.json() + if detect_secrets_output: + secrets_string = ", ".join( + [ + f"{secret['type']} on line {secret['line_number']}" + for secret in detect_secrets_output[temp_env_data_file.name] + ] + ) report.status = "FAIL" - report.status_extended = f"Potential secret found in variables of ECS task definition {task_definition.name} with revision {task_definition.revision}" + report.status_extended = f"Potential secret found in variables of ECS task definition {task_definition.name} with revision {task_definition.revision} -> {secrets_string}" os.remove(temp_env_data_file.name) diff --git a/prowler/providers/aws/services/ssm/ssm_document_secrets/ssm_document_secrets.py b/prowler/providers/aws/services/ssm/ssm_document_secrets/ssm_document_secrets.py index b184983d..82a10cc0 100644 --- a/prowler/providers/aws/services/ssm/ssm_document_secrets/ssm_document_secrets.py +++ b/prowler/providers/aws/services/ssm/ssm_document_secrets/ssm_document_secrets.py @@ -24,18 +24,26 @@ class ssm_document_secrets(Check): if document.content: temp_env_data_file = tempfile.NamedTemporaryFile(delete=False) temp_env_data_file.write( - bytes(json.dumps(document.content), encoding="raw_unicode_escape") + bytes( + json.dumps(document.content, indent=2), + encoding="raw_unicode_escape", + ) ) temp_env_data_file.close() secrets = SecretsCollection() with default_settings(): secrets.scan_file(temp_env_data_file.name) - if secrets.json(): - report.status = "FAIL" - report.status_extended = ( - f"Potential secret found in SSM Document {document.name}" + detect_secrets_output = secrets.json() + if detect_secrets_output: + secrets_string = ", ".join( + [ + f"{secret['type']} on line {secret['line_number']}" + for secret in detect_secrets_output[temp_env_data_file.name] + ] ) + report.status = "FAIL" + report.status_extended = f"Potential secret found in SSM Document {document.name} -> {secrets_string}" os.remove(temp_env_data_file.name) diff --git a/tests/providers/aws/services/awslambda/awslambda_function_no_secrets_in_code/awslambda_function_no_secrets_in_code_test.py b/tests/providers/aws/services/awslambda/awslambda_function_no_secrets_in_code/awslambda_function_no_secrets_in_code_test.py index f8a68669..4b959a80 100644 --- a/tests/providers/aws/services/awslambda/awslambda_function_no_secrets_in_code/awslambda_function_no_secrets_in_code_test.py +++ b/tests/providers/aws/services/awslambda/awslambda_function_no_secrets_in_code/awslambda_function_no_secrets_in_code_test.py @@ -76,7 +76,7 @@ class Test_awslambda_function_no_secrets_in_code: assert result[0].status == "FAIL" assert ( result[0].status_extended - == f"Potential secret found in Lambda function {function_name} code" + == f"Potential secret found in Lambda function {function_name} code -> lambda_function.py: Secret Keyword on line 3" ) def test_function_code_without_secrets(self): diff --git a/tests/providers/aws/services/awslambda/awslambda_function_no_secrets_in_variables/awslambda_function_no_secrets_in_variables_test.py b/tests/providers/aws/services/awslambda/awslambda_function_no_secrets_in_variables/awslambda_function_no_secrets_in_variables_test.py index 7025f957..0c590fc2 100644 --- a/tests/providers/aws/services/awslambda/awslambda_function_no_secrets_in_variables/awslambda_function_no_secrets_in_variables_test.py +++ b/tests/providers/aws/services/awslambda/awslambda_function_no_secrets_in_variables/awslambda_function_no_secrets_in_variables_test.py @@ -102,7 +102,7 @@ class Test_awslambda_function_no_secrets_in_variables: assert result[0].status == "FAIL" assert ( result[0].status_extended - == f"Potential secret found in Lambda function {function_name} variables" + == f"Potential secret found in Lambda function {function_name} variables -> Secret Keyword in variable db_password" ) def test_function_no_secrets_in_variables(self): diff --git a/tests/providers/aws/services/ecs/ecs_task_definitions_no_environment_secrets/ecs_task_definitions_no_environment_secrets_test.py b/tests/providers/aws/services/ecs/ecs_task_definitions_no_environment_secrets/ecs_task_definitions_no_environment_secrets_test.py index 40f3c4fe..40e03067 100644 --- a/tests/providers/aws/services/ecs/ecs_task_definitions_no_environment_secrets/ecs_task_definitions_no_environment_secrets_test.py +++ b/tests/providers/aws/services/ecs/ecs_task_definitions_no_environment_secrets/ecs_task_definitions_no_environment_secrets_test.py @@ -102,7 +102,7 @@ class Test_ecs_task_definitions_no_environment_secrets: assert result[0].status == "FAIL" assert ( result[0].status_extended - == f"Potential secret found in variables of ECS task definition {task_name} with revision {task_revision}" + == f"Potential secret found in variables of ECS task definition {task_name} with revision {task_revision} -> Secret Keyword on line 2" ) assert result[0].resource_id == f"{task_name}:1" assert ( diff --git a/tests/providers/aws/services/ssm/ssm_document_secrets/ssm_document_secrets_test.py b/tests/providers/aws/services/ssm/ssm_document_secrets/ssm_document_secrets_test.py index 374fc957..42408859 100644 --- a/tests/providers/aws/services/ssm/ssm_document_secrets/ssm_document_secrets_test.py +++ b/tests/providers/aws/services/ssm/ssm_document_secrets/ssm_document_secrets_test.py @@ -59,7 +59,7 @@ class Test_ssm_documents_secrets: assert result[0].status == "FAIL" assert ( result[0].status_extended - == f"Potential secret found in SSM Document {document_name}" + == f"Potential secret found in SSM Document {document_name} -> Secret Keyword on line 2" ) def test_document_no_secrets(self):