fix(aws): key error for detect-secrets (#6865)

Co-authored-by: Kay Agahd <kagahd@users.noreply.github.com>
This commit is contained in:
Prowler Bot
2025-02-07 16:04:54 +01:00
committed by GitHub
parent 58e7589c9d
commit 7189f3d526
4 changed files with 274 additions and 26 deletions

View File

@@ -1,4 +1,3 @@
import hashlib
import json
from prowler.lib.check.models import Check, Check_Report_AWS
@@ -28,19 +27,13 @@ class awslambda_function_no_secrets_in_variables(Check):
"detect_secrets_plugins",
),
)
original_env_vars = {}
original_env_vars = []
for name, value in function.environment.items():
original_env_vars.update(
{
hashlib.sha1( # nosec B324 SHA1 is used here for non-security-critical unique identifiers
value.encode("utf-8")
).hexdigest(): name
}
)
original_env_vars.append(name)
if detect_secrets_output:
secrets_string = ", ".join(
[
f"{secret['type']} in variable {original_env_vars[secret['hashed_secret']]}"
f"{secret['type']} in variable {original_env_vars[secret['line_number'] - 2]}"
for secret in detect_secrets_output
]
)

View File

@@ -1,4 +1,3 @@
import hashlib
from json import dumps
from prowler.lib.check.models import Check, Check_Report_AWS
@@ -25,16 +24,10 @@ class ecs_task_definitions_no_environment_secrets(Check):
if container.environment:
dump_env_vars = {}
original_env_vars = {}
original_env_vars = []
for env_var in container.environment:
dump_env_vars.update({env_var.name: env_var.value})
original_env_vars.update(
{
hashlib.sha1( # nosec B324 SHA1 is used here for non-security-critical unique identifiers
env_var.value.encode("utf-8")
).hexdigest(): env_var.name
}
)
original_env_vars.append(env_var.name)
env_data = dumps(dump_env_vars, indent=2)
detect_secrets_output = detect_secrets_scan(
@@ -47,7 +40,7 @@ class ecs_task_definitions_no_environment_secrets(Check):
if detect_secrets_output:
secrets_string = ", ".join(
[
f"{secret['type']} on the environment variable {original_env_vars[secret['hashed_secret']]}"
f"{secret['type']} on the environment variable {original_env_vars[secret['line_number'] - 2]}"
for secret in detect_secrets_output
]
)

View File

@@ -76,7 +76,7 @@ class Test_awslambda_function_no_secrets_in_variables:
)
assert result[0].resource_tags == []
def test_function_secrets_in_variables(self):
def test_function_secrets_in_keyword(self):
lambda_client = mock.MagicMock
function_name = "test-lambda"
function_runtime = "nodejs4.3"
@@ -121,6 +121,51 @@ class Test_awslambda_function_no_secrets_in_variables:
)
assert result[0].resource_tags == []
def test_function_secrets_in_keyword_and_variable(self):
lambda_client = mock.MagicMock
function_name = "test-lambda"
function_runtime = "nodejs4.3"
function_arn = f"arn:aws:lambda:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:function/{function_name}"
lambda_client.audit_config = {"secrets_ignore_patterns": []}
lambda_client.functions = {
"function_name": Function(
name=function_name,
security_groups=[],
arn=function_arn,
region=AWS_REGION_US_EAST_1,
runtime=function_runtime,
environment={"db_password": "srv://admin:pass@db"},
)
}
with mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_aws_provider(),
), mock.patch(
"prowler.providers.aws.services.awslambda.awslambda_function_no_secrets_in_variables.awslambda_function_no_secrets_in_variables.awslambda_client",
new=lambda_client,
):
# Test Check
from prowler.providers.aws.services.awslambda.awslambda_function_no_secrets_in_variables.awslambda_function_no_secrets_in_variables import (
awslambda_function_no_secrets_in_variables,
)
check = awslambda_function_no_secrets_in_variables()
result = check.execute()
assert len(result) == 1
assert result[0].region == AWS_REGION_US_EAST_1
assert result[0].resource_id == function_name
assert result[0].resource_arn == function_arn
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"Potential secret found in Lambda function {function_name} variables -> Secret Keyword in variable db_password, Basic Auth Credentials in variable db_password."
)
assert result[0].resource_tags == []
def test_function_secrets_in_variables_telegram_token(self):
lambda_client = mock.MagicMock
function_name = "test-lambda"

View File

@@ -2,7 +2,6 @@ from unittest.mock import patch
from boto3 import client
from moto import mock_aws
from tests.providers.aws.utils import AWS_REGION_US_EAST_1, set_mocked_aws_provider
TASK_NAME = "test-task"
@@ -10,8 +9,10 @@ TASK_REVISION = "1"
CONTAINER_NAME = "test-container"
ENV_VAR_NAME_NO_SECRETS = "host"
ENV_VAR_VALUE_NO_SECRETS = "localhost:1234"
ENV_VAR_NAME_WITH_SECRETS = "DB_PASSWORD"
ENV_VAR_VALUE_WITH_SECRETS = "pass-12343"
ENV_VAR_NAME_WITH_KEYWORD = "DB_PASSWORD"
ENV_VAR_VALUE_WITH_SECRETS = "srv://admin:pass@db"
ENV_VAR_NAME_WITH_KEYWORD2 = "DATABASE_PASSWORD"
ENV_VAR_VALUE_WITH_SECRETS2 = "srv://admin:password@database"
class Test_ecs_task_definitions_no_environment_secrets:
@@ -88,7 +89,7 @@ class Test_ecs_task_definitions_no_environment_secrets:
assert result[0].resource_tags == []
@mock_aws
def test_container_env_var_with_secrets(self):
def test_container_env_var_with_secret(self):
ecs_client = client("ecs", region_name=AWS_REGION_US_EAST_1)
task_arn = ecs_client.register_task_definition(
@@ -103,7 +104,7 @@ class Test_ecs_task_definitions_no_environment_secrets:
"user": "appuser",
"environment": [
{
"name": ENV_VAR_NAME_WITH_SECRETS,
"name": ENV_VAR_NAME_NO_SECRETS,
"value": ENV_VAR_VALUE_WITH_SECRETS,
}
],
@@ -115,6 +116,58 @@ class Test_ecs_task_definitions_no_environment_secrets:
mocked_aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
with patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mocked_aws_provider,
), patch(
"prowler.providers.aws.services.ecs.ecs_task_definitions_no_environment_secrets.ecs_task_definitions_no_environment_secrets.ecs_client",
new=ECS(mocked_aws_provider),
):
from prowler.providers.aws.services.ecs.ecs_task_definitions_no_environment_secrets.ecs_task_definitions_no_environment_secrets import (
ecs_task_definitions_no_environment_secrets,
)
check = ecs_task_definitions_no_environment_secrets()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"Potential secrets found in ECS task definition {TASK_NAME} with revision {TASK_REVISION}: Secrets in container test-container -> Basic Auth Credentials on the environment variable host."
)
assert result[0].resource_id == f"{TASK_NAME}:{TASK_REVISION}"
assert result[0].resource_arn == task_arn
assert result[0].region == AWS_REGION_US_EAST_1
assert result[0].resource_tags == []
@mock_aws
def test_container_env_var_with_keyword(self):
ecs_client = client("ecs", region_name=AWS_REGION_US_EAST_1)
task_arn = ecs_client.register_task_definition(
family=TASK_NAME,
containerDefinitions=[
{
"name": CONTAINER_NAME,
"image": "ubuntu",
"memory": 128,
"readonlyRootFilesystem": True,
"privileged": False,
"user": "appuser",
"environment": [
{
"name": ENV_VAR_NAME_WITH_KEYWORD,
"value": ENV_VAR_VALUE_NO_SECRETS,
}
],
}
],
)["taskDefinition"]["taskDefinitionArn"]
from prowler.providers.aws.services.ecs.ecs_service import ECS
mocked_aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
with patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mocked_aws_provider,
@@ -138,3 +191,167 @@ class Test_ecs_task_definitions_no_environment_secrets:
assert result[0].resource_arn == task_arn
assert result[0].region == AWS_REGION_US_EAST_1
assert result[0].resource_tags == []
@mock_aws
def test_container_env_var_with_keyword_and_secret(self):
ecs_client = client("ecs", region_name=AWS_REGION_US_EAST_1)
task_arn = ecs_client.register_task_definition(
family=TASK_NAME,
containerDefinitions=[
{
"name": CONTAINER_NAME,
"image": "ubuntu",
"memory": 128,
"readonlyRootFilesystem": True,
"privileged": False,
"user": "appuser",
"environment": [
{
"name": ENV_VAR_NAME_WITH_KEYWORD,
"value": ENV_VAR_VALUE_WITH_SECRETS,
}
],
}
],
)["taskDefinition"]["taskDefinitionArn"]
from prowler.providers.aws.services.ecs.ecs_service import ECS
mocked_aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
with patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mocked_aws_provider,
), patch(
"prowler.providers.aws.services.ecs.ecs_task_definitions_no_environment_secrets.ecs_task_definitions_no_environment_secrets.ecs_client",
new=ECS(mocked_aws_provider),
):
from prowler.providers.aws.services.ecs.ecs_task_definitions_no_environment_secrets.ecs_task_definitions_no_environment_secrets import (
ecs_task_definitions_no_environment_secrets,
)
check = ecs_task_definitions_no_environment_secrets()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"Potential secrets found in ECS task definition {TASK_NAME} with revision {TASK_REVISION}: Secrets in container test-container -> Secret Keyword on the environment variable DB_PASSWORD, Basic Auth Credentials on the environment variable DB_PASSWORD."
)
assert result[0].resource_id == f"{TASK_NAME}:{TASK_REVISION}"
assert result[0].resource_arn == task_arn
assert result[0].region == AWS_REGION_US_EAST_1
assert result[0].resource_tags == []
@mock_aws
def test_container_multiple_env_vars_with_keyword_and_secret(self):
ecs_client = client("ecs", region_name=AWS_REGION_US_EAST_1)
task_arn = ecs_client.register_task_definition(
family=TASK_NAME,
containerDefinitions=[
{
"name": CONTAINER_NAME,
"image": "ubuntu",
"memory": 128,
"readonlyRootFilesystem": True,
"privileged": False,
"user": "appuser",
"environment": [
{
"name": ENV_VAR_NAME_WITH_KEYWORD,
"value": ENV_VAR_VALUE_WITH_SECRETS,
},
{
"name": ENV_VAR_NAME_NO_SECRETS,
"value": ENV_VAR_VALUE_WITH_SECRETS2,
},
],
}
],
)["taskDefinition"]["taskDefinitionArn"]
from prowler.providers.aws.services.ecs.ecs_service import ECS
mocked_aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
with patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mocked_aws_provider,
), patch(
"prowler.providers.aws.services.ecs.ecs_task_definitions_no_environment_secrets.ecs_task_definitions_no_environment_secrets.ecs_client",
new=ECS(mocked_aws_provider),
):
from prowler.providers.aws.services.ecs.ecs_task_definitions_no_environment_secrets.ecs_task_definitions_no_environment_secrets import (
ecs_task_definitions_no_environment_secrets,
)
check = ecs_task_definitions_no_environment_secrets()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"Potential secrets found in ECS task definition {TASK_NAME} with revision {TASK_REVISION}: Secrets in container test-container -> Secret Keyword on the environment variable DB_PASSWORD, Basic Auth Credentials on the environment variable DB_PASSWORD, Basic Auth Credentials on the environment variable host."
)
assert result[0].resource_id == f"{TASK_NAME}:{TASK_REVISION}"
assert result[0].resource_arn == task_arn
assert result[0].region == AWS_REGION_US_EAST_1
assert result[0].resource_tags == []
@mock_aws
def test_container_all_env_vars_with_keyword_and_secret(self):
ecs_client = client("ecs", region_name=AWS_REGION_US_EAST_1)
task_arn = ecs_client.register_task_definition(
family=TASK_NAME,
containerDefinitions=[
{
"name": CONTAINER_NAME,
"image": "ubuntu",
"memory": 128,
"readonlyRootFilesystem": True,
"privileged": False,
"user": "appuser",
"environment": [
{
"name": ENV_VAR_NAME_WITH_KEYWORD,
"value": ENV_VAR_VALUE_WITH_SECRETS,
},
{
"name": ENV_VAR_NAME_WITH_KEYWORD2,
"value": ENV_VAR_VALUE_WITH_SECRETS2,
},
],
}
],
)["taskDefinition"]["taskDefinitionArn"]
from prowler.providers.aws.services.ecs.ecs_service import ECS
mocked_aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
with patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mocked_aws_provider,
), patch(
"prowler.providers.aws.services.ecs.ecs_task_definitions_no_environment_secrets.ecs_task_definitions_no_environment_secrets.ecs_client",
new=ECS(mocked_aws_provider),
):
from prowler.providers.aws.services.ecs.ecs_task_definitions_no_environment_secrets.ecs_task_definitions_no_environment_secrets import (
ecs_task_definitions_no_environment_secrets,
)
check = ecs_task_definitions_no_environment_secrets()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"Potential secrets found in ECS task definition {TASK_NAME} with revision {TASK_REVISION}: Secrets in container test-container -> Secret Keyword on the environment variable DB_PASSWORD, Basic Auth Credentials on the environment variable DB_PASSWORD, Basic Auth Credentials on the environment variable DATABASE_PASSWORD, Secret Keyword on the environment variable DATABASE_PASSWORD."
)
assert result[0].resource_id == f"{TASK_NAME}:{TASK_REVISION}"
assert result[0].resource_arn == task_arn
assert result[0].region == AWS_REGION_US_EAST_1
assert result[0].resource_tags == []