-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(ecs): Ensure ECS containers have a logging configuration specifi…
…ed (#5234) Co-authored-by: Sergio Garcia <[email protected]>
- Loading branch information
1 parent
3db541a
commit 30e3fd9
Showing
12 changed files
with
247 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
34 changes: 34 additions & 0 deletions
34
...s/ecs_task_definitions_logging_enabled/ecs_task_definitions_logging_enabled.metadata.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
{ | ||
"Provider": "aws", | ||
"CheckID": "ecs_task_definitions_logging_enabled", | ||
"CheckTitle": "ECS task definitions containers should have a logging configuration", | ||
"CheckType": [ | ||
"Software and Configuration Checks/AWS Security Best Practices" | ||
], | ||
"ServiceName": "ecs", | ||
"SubServiceName": "", | ||
"ResourceIdTemplate": "arn:aws:ecs:{region}:{account-id}:task-definition/{task-definition-name}", | ||
"Severity": "high", | ||
"ResourceType": "AwsEcsTaskDefinition", | ||
"Description": "This control checks if the latest active Amazon ECS task definition has a logging configuration specified. The control fails if the task definition doesn't have the logConfiguration property defined or if the value for logDriver is null in at least one container definition.", | ||
"Risk": "Without a logging configuration, important data may be lost, making it difficult to troubleshoot issues, monitor performance, and ensure compliance with auditing requirements.", | ||
"RelatedUrl": "https://docs.aws.amazon.com/config/latest/developerguide/ecs-task-definition-log-configuration.html", | ||
"Remediation": { | ||
"Code": { | ||
"CLI": "aws ecs register-task-definition --family <task-family> --container-definitions '[{\"name\":\"<container-name>\",\"image\":\"<image>\",\"logConfiguration\":{\"logDriver\":\"awslogs\",\"options\":{\"awslogs-group\":\"<log-group>\",\"awslogs-region\":\"<region>\",\"awslogs-stream-prefix\":\"ecs\"}}}]'", | ||
"NativeIaC": "", | ||
"Other": "https://docs.aws.amazon.com/securityhub/latest/userguide/ecs-controls.html#ecs-9", | ||
"Terraform": "" | ||
}, | ||
"Recommendation": { | ||
"Text": "Define a logging configuration in the ECS task definition to ensure important data is captured and available for debugging, monitoring, and auditing purposes.", | ||
"Url": "https://docs.aws.amazon.com/AmazonECS/latest/developerguide/using_awslogs.html#specify-log-config" | ||
} | ||
}, | ||
"Categories": [ | ||
"logging" | ||
], | ||
"DependsOn": [], | ||
"RelatedTo": [], | ||
"Notes": "" | ||
} |
26 changes: 26 additions & 0 deletions
26
...services/ecs/ecs_task_definitions_logging_enabled/ecs_task_definitions_logging_enabled.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
from prowler.lib.check.models import Check, Check_Report_AWS | ||
from prowler.providers.aws.services.ecs.ecs_client import ecs_client | ||
|
||
|
||
class ecs_task_definitions_logging_enabled(Check): | ||
def execute(self): | ||
findings = [] | ||
for task_definition in ecs_client.task_definitions.values(): | ||
report = Check_Report_AWS(self.metadata()) | ||
report.region = task_definition.region | ||
report.resource_id = f"{task_definition.name}:{task_definition.revision}" | ||
report.resource_arn = task_definition.arn | ||
report.resource_tags = task_definition.tags | ||
report.status = "PASS" | ||
report.status_extended = f"ECS task definition {task_definition.name} with revision {task_definition.revision} containers have logging configured." | ||
failed_containers = [] | ||
for container in task_definition.container_definitions: | ||
if not container.log_driver: | ||
report.status = "FAIL" | ||
failed_containers.append(container.name) | ||
|
||
if failed_containers: | ||
report.status_extended = f"ECS task definition {task_definition.name} with revision {task_definition.revision} has containers running with no logging configuration: {', '.join(failed_containers)}" | ||
|
||
findings.append(report) | ||
return findings |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
166 changes: 166 additions & 0 deletions
166
...ces/ecs/ecs_task_definitions_logging_enabled/ecs_task_definitions_logging_enabled_test.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
from unittest import mock | ||
|
||
import botocore | ||
|
||
from prowler.providers.aws.services.ecs.ecs_service import ( | ||
ContainerDefinition, | ||
TaskDefinition, | ||
) | ||
from tests.providers.aws.utils import ( | ||
AWS_ACCOUNT_NUMBER, | ||
AWS_REGION_US_EAST_1, | ||
set_mocked_aws_provider, | ||
) | ||
|
||
TASK_NAME = "test-task" | ||
TASK_REVISION = "1" | ||
CONTAINER_NAME = "test-container" | ||
TASK_ARN = f"arn:aws:ecs:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:task-definition/{TASK_NAME}:{TASK_REVISION}" | ||
|
||
|
||
make_api_call = botocore.client.BaseClient._make_api_call | ||
|
||
|
||
def mock_make_api_call(self, operation_name, kwarg): | ||
if operation_name == "ListTaskDefinitions": | ||
return { | ||
"taskDefinitionArns": [ | ||
"arn:aws:ecs:eu-west-1:123456789012:task-definition/test-task:1" | ||
] | ||
} | ||
if operation_name == "DescribeTaskDefinition": | ||
return { | ||
"taskDefinition": { | ||
"containerDefinitions": [ | ||
{ | ||
"name": "test-container", | ||
"image": "test-image", | ||
"environment": [ | ||
{"name": "DB_PASSWORD", "value": "pass-12343"}, | ||
], | ||
} | ||
], | ||
"networkMode": "host", | ||
"tags": [], | ||
} | ||
} | ||
return make_api_call(self, operation_name, kwarg) | ||
|
||
|
||
class Test_ecs_task_definitions_logging_enabled: | ||
def test_no_task_definitions(self): | ||
ecs_client = mock.MagicMock | ||
ecs_client.task_definitions = {} | ||
|
||
with mock.patch( | ||
"prowler.providers.aws.services.ecs.ecs_service.ECS", | ||
ecs_client, | ||
): | ||
from prowler.providers.aws.services.ecs.ecs_task_definitions_logging_enabled.ecs_task_definitions_logging_enabled import ( | ||
ecs_task_definitions_logging_enabled, | ||
) | ||
|
||
check = ecs_task_definitions_logging_enabled() | ||
result = check.execute() | ||
assert len(result) == 0 | ||
|
||
@mock.patch("botocore.client.BaseClient._make_api_call", new=mock_make_api_call) | ||
def test_task_definition_no_logconfiguration(self): | ||
|
||
from prowler.providers.aws.services.ecs.ecs_service import ECS | ||
|
||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) | ||
|
||
with mock.patch( | ||
"prowler.providers.common.provider.Provider.get_global_provider", | ||
return_value=aws_provider, | ||
), mock.patch( | ||
"prowler.providers.aws.services.ecs.ecs_task_definitions_logging_enabled.ecs_task_definitions_logging_enabled.ecs_client", | ||
new=ECS(aws_provider), | ||
): | ||
from prowler.providers.aws.services.ecs.ecs_task_definitions_logging_enabled.ecs_task_definitions_logging_enabled import ( | ||
ecs_task_definitions_logging_enabled, | ||
) | ||
|
||
check = ecs_task_definitions_logging_enabled() | ||
result = check.execute() | ||
assert len(result) == 1 | ||
assert result[0].status == "FAIL" | ||
assert ( | ||
result[0].status_extended | ||
== f"ECS task definition {TASK_NAME} with revision {TASK_REVISION} has containers running with no logging configuration: {CONTAINER_NAME}" | ||
) | ||
|
||
def test_task_definition_no_logdriver(self): | ||
ecs_client = mock.MagicMock | ||
ecs_client.task_definitions = {} | ||
ecs_client.task_definitions[TASK_ARN] = TaskDefinition( | ||
name=TASK_NAME, | ||
arn=TASK_ARN, | ||
revision=TASK_REVISION, | ||
region=AWS_REGION_US_EAST_1, | ||
network_mode="host", | ||
container_definitions=[ | ||
ContainerDefinition( | ||
name=CONTAINER_NAME, | ||
privileged=True, | ||
user="root", | ||
environment=[], | ||
log_driver="", | ||
) | ||
], | ||
) | ||
|
||
with mock.patch( | ||
"prowler.providers.aws.services.ecs.ecs_service.ECS", | ||
ecs_client, | ||
): | ||
from prowler.providers.aws.services.ecs.ecs_task_definitions_logging_enabled.ecs_task_definitions_logging_enabled import ( | ||
ecs_task_definitions_logging_enabled, | ||
) | ||
|
||
check = ecs_task_definitions_logging_enabled() | ||
result = check.execute() | ||
assert len(result) == 1 | ||
assert result[0].status == "FAIL" | ||
assert ( | ||
result[0].status_extended | ||
== f"ECS task definition {TASK_NAME} with revision {TASK_REVISION} has containers running with no logging configuration: {CONTAINER_NAME}" | ||
) | ||
|
||
def test_task_definition_privileged_container(self): | ||
ecs_client = mock.MagicMock | ||
ecs_client.task_definitions = {} | ||
ecs_client.task_definitions[TASK_ARN] = TaskDefinition( | ||
name=TASK_NAME, | ||
arn=TASK_ARN, | ||
revision=TASK_REVISION, | ||
region=AWS_REGION_US_EAST_1, | ||
network_mode="host", | ||
container_definitions=[ | ||
ContainerDefinition( | ||
name=CONTAINER_NAME, | ||
privileged=True, | ||
user="root", | ||
environment=[], | ||
log_driver="awslogs", | ||
) | ||
], | ||
) | ||
|
||
with mock.patch( | ||
"prowler.providers.aws.services.ecs.ecs_service.ECS", | ||
ecs_client, | ||
): | ||
from prowler.providers.aws.services.ecs.ecs_task_definitions_logging_enabled.ecs_task_definitions_logging_enabled import ( | ||
ecs_task_definitions_logging_enabled, | ||
) | ||
|
||
check = ecs_task_definitions_logging_enabled() | ||
result = check.execute() | ||
assert len(result) == 1 | ||
assert result[0].status == "PASS" | ||
assert ( | ||
result[0].status_extended | ||
== f"ECS task definition {TASK_NAME} with revision {TASK_REVISION} containers have logging configured." | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters