mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-01-25 02:08:11 +00:00
fix(aws): key error for detect-secrets (#6865)
Co-authored-by: Kay Agahd <kagahd@users.noreply.github.com>
This commit is contained in:
@@ -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
|
||||
]
|
||||
)
|
||||
|
||||
@@ -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
|
||||
]
|
||||
)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 == []
|
||||
|
||||
Reference in New Issue
Block a user