mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-23 12:31:54 +00:00
feat(ecs): add new check ecs_service_fargate_latest_platform_version (#5258)
Co-authored-by: Sergio <sergio@prowler.com>
This commit is contained in:
committed by
GitHub
parent
158263a8bf
commit
2ffe7f3ef7
@@ -57,6 +57,11 @@ aws:
|
||||
8088,
|
||||
]
|
||||
|
||||
# AWS ECS Configuration
|
||||
# aws.ecs_service_fargate_latest_platform_version
|
||||
fargate_linux_latest_version: "1.4.0"
|
||||
fargate_windows_latest_version: "1.0.0"
|
||||
|
||||
# AWS VPC Configuration (vpc_endpoint_connections_trust_boundaries, vpc_endpoint_services_allowed_principals_trust_boundaries)
|
||||
# AWS SSM Configuration (aws.ssm_documents_set_as_public)
|
||||
# Single account environment: No action required. The AWS account number will be automatically added by the checks.
|
||||
|
||||
@@ -120,6 +120,9 @@ class ECS(AWSService):
|
||||
.get("assignPublicIp", "DISABLED")
|
||||
== "ENABLED"
|
||||
),
|
||||
launch_type=service_desc.get("launchType", ""),
|
||||
platform_version=service_desc.get("platformVersion", ""),
|
||||
platform_family=service_desc.get("platformFamily", ""),
|
||||
tags=service_desc.get("tags", []),
|
||||
)
|
||||
cluster.services[service_arn] = service_obj
|
||||
@@ -195,6 +198,9 @@ class Service(BaseModel):
|
||||
name: str
|
||||
arn: str
|
||||
region: str
|
||||
launch_type: str = ""
|
||||
platform_version: Optional[str]
|
||||
platform_family: Optional[str]
|
||||
assign_public_ip: Optional[bool]
|
||||
tags: Optional[list] = []
|
||||
|
||||
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"Provider": "aws",
|
||||
"CheckID": "ecs_service_fargate_latest_platform_version",
|
||||
"CheckTitle": "ECS Fargate services should run on the latest Fargate platform version",
|
||||
"CheckType": [
|
||||
"Software and Configuration Checks/AWS Security Best Practices"
|
||||
],
|
||||
"ServiceName": "ecs",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "arn:aws:ecs:{region}:{account-id}:service/{service-name}",
|
||||
"Severity": "medium",
|
||||
"ResourceType": "AwsEcsService",
|
||||
"Description": "This control checks if Amazon ECS Fargate services are running the latest Fargate platform version. The control fails if the platform version is not the latest.",
|
||||
"Risk": "Not running the latest Fargate platform version may expose your services to security vulnerabilities and bugs that are resolved in newer versions.",
|
||||
"RelatedUrl": "https://docs.aws.amazon.com/config/latest/developerguide/ecs-fargate-latest-platform-version.html",
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "aws ecs update-service --cluster <cluster-name> --service <service-name> --platform-version LATEST",
|
||||
"NativeIaC": "",
|
||||
"Other": "https://docs.aws.amazon.com/securityhub/latest/userguide/ecs-controls.html#ecs-10",
|
||||
"Terraform": ""
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "Update your ECS Fargate services to the latest platform version to ensure they are running in a secure and optimized environment.",
|
||||
"Url": "https://docs.aws.amazon.com/AmazonECS/latest/developerguide/Welcome.html"
|
||||
}
|
||||
},
|
||||
"Categories": [
|
||||
"vulnerabilities"
|
||||
],
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": ""
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
from prowler.lib.check.models import Check, Check_Report_AWS
|
||||
from prowler.providers.aws.services.ecs.ecs_client import ecs_client
|
||||
|
||||
|
||||
class ecs_service_fargate_latest_platform_version(Check):
|
||||
def execute(self):
|
||||
findings = []
|
||||
for service in ecs_client.services.values():
|
||||
if service.launch_type == "FARGATE":
|
||||
report = Check_Report_AWS(self.metadata())
|
||||
report.region = service.region
|
||||
report.resource_id = service.name
|
||||
report.resource_arn = service.arn
|
||||
report.resource_tags = service.tags
|
||||
fargate_latest_linux_version = ecs_client.audit_config.get(
|
||||
"fargate_linux_latest_version", "1.4.0"
|
||||
)
|
||||
fargate_latest_windows_version = ecs_client.audit_config.get(
|
||||
"fargate_windows_latest_version", "1.0.0"
|
||||
)
|
||||
report.status = "PASS"
|
||||
report.status_extended = f"ECS Service {service.name} is using latest FARGATE {service.platform_family} version {fargate_latest_linux_version if service.platform_family == 'Linux' else fargate_latest_windows_version}."
|
||||
if (
|
||||
service.platform_version != "LATEST"
|
||||
and (
|
||||
service.platform_family == "Linux"
|
||||
and service.platform_version != fargate_latest_linux_version
|
||||
)
|
||||
or (
|
||||
service.platform_family == "Windows"
|
||||
and service.platform_version != fargate_latest_windows_version
|
||||
)
|
||||
):
|
||||
report.status = "FAIL"
|
||||
report.status_extended = f"ECS Service {service.name} is not using latest FARGATE {service.platform_family} version {fargate_latest_linux_version if service.platform_family == 'Linux' else fargate_latest_windows_version}, currently using {service.platform_version}."
|
||||
|
||||
findings.append(report)
|
||||
return findings
|
||||
@@ -93,6 +93,8 @@ config_aws = {
|
||||
8080,
|
||||
8088,
|
||||
],
|
||||
"fargate_linux_latest_version": "1.4.0",
|
||||
"fargate_windows_latest_version": "1.0.0",
|
||||
"trusted_account_ids": [],
|
||||
"log_group_retention_days": 365,
|
||||
"max_idle_disconnect_timeout_in_seconds": 600,
|
||||
|
||||
@@ -57,6 +57,11 @@ aws:
|
||||
8088,
|
||||
]
|
||||
|
||||
# AWS ECS Configuration
|
||||
# aws.ecs_service_fargate_latest_platform_version
|
||||
fargate_linux_latest_version: "1.4.0"
|
||||
fargate_windows_latest_version: "1.0.0"
|
||||
|
||||
# AWS VPC Configuration (vpc_endpoint_connections_trust_boundaries, vpc_endpoint_services_allowed_principals_trust_boundaries)
|
||||
# AWS SSM Configuration (aws.ssm_documents_set_as_public)
|
||||
# Single account environment: No action required. The AWS account number will be automatically added by the checks.
|
||||
|
||||
+195
@@ -0,0 +1,195 @@
|
||||
from unittest import mock
|
||||
|
||||
from prowler.providers.aws.services.ecs.ecs_service import Service
|
||||
from tests.providers.aws.utils import AWS_ACCOUNT_NUMBER, AWS_REGION_US_EAST_1
|
||||
|
||||
SERVICE_ARN = (
|
||||
f"arn:aws:ecs:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:service/sample-service"
|
||||
)
|
||||
SERVICE_NAME = "sample-service"
|
||||
|
||||
|
||||
class Test_ecs_service_fargate_latest_platform_version:
|
||||
def test_no_services(self):
|
||||
ecs_client = mock.MagicMock
|
||||
ecs_client.services = {}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.ecs.ecs_service.ECS",
|
||||
ecs_client,
|
||||
):
|
||||
from prowler.providers.aws.services.ecs.ecs_service_fargate_latest_platform_version.ecs_service_fargate_latest_platform_version import (
|
||||
ecs_service_fargate_latest_platform_version,
|
||||
)
|
||||
|
||||
check = ecs_service_fargate_latest_platform_version()
|
||||
result = check.execute()
|
||||
assert len(result) == 0
|
||||
|
||||
def test_service_ec2_type(self):
|
||||
ecs_client = mock.MagicMock
|
||||
ecs_client.services = {}
|
||||
ecs_client.services[SERVICE_ARN] = Service(
|
||||
name=SERVICE_NAME,
|
||||
arn=SERVICE_ARN,
|
||||
region=AWS_REGION_US_EAST_1,
|
||||
launch_type="EC2",
|
||||
assign_public_ip=False,
|
||||
tags=[],
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.ecs.ecs_service.ECS",
|
||||
ecs_client,
|
||||
):
|
||||
from prowler.providers.aws.services.ecs.ecs_service_fargate_latest_platform_version.ecs_service_fargate_latest_platform_version import (
|
||||
ecs_service_fargate_latest_platform_version,
|
||||
)
|
||||
|
||||
check = ecs_service_fargate_latest_platform_version()
|
||||
result = check.execute()
|
||||
assert len(result) == 0
|
||||
|
||||
def test_service_linux_latest_version(self):
|
||||
ecs_client = mock.MagicMock
|
||||
ecs_client.services = {}
|
||||
ecs_client.services[SERVICE_ARN] = Service(
|
||||
name=SERVICE_NAME,
|
||||
arn=SERVICE_ARN,
|
||||
region=AWS_REGION_US_EAST_1,
|
||||
launch_type="FARGATE",
|
||||
platform_family="Linux",
|
||||
platform_version="1.4.0",
|
||||
assign_public_ip=False,
|
||||
tags=[],
|
||||
)
|
||||
|
||||
ecs_client.audit_config = {
|
||||
"fargate_linux_latest_version": "1.4.0",
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.ecs.ecs_service.ECS",
|
||||
ecs_client,
|
||||
):
|
||||
from prowler.providers.aws.services.ecs.ecs_service_fargate_latest_platform_version.ecs_service_fargate_latest_platform_version import (
|
||||
ecs_service_fargate_latest_platform_version,
|
||||
)
|
||||
|
||||
check = ecs_service_fargate_latest_platform_version()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert result[0].status_extended == (
|
||||
f"ECS Service {SERVICE_NAME} is using latest FARGATE Linux version 1.4.0."
|
||||
)
|
||||
assert result[0].resource_id == SERVICE_NAME
|
||||
assert result[0].resource_arn == SERVICE_ARN
|
||||
|
||||
def test_service_windows_latest_version(self):
|
||||
ecs_client = mock.MagicMock
|
||||
ecs_client.services = {}
|
||||
ecs_client.services[SERVICE_ARN] = Service(
|
||||
name=SERVICE_NAME,
|
||||
arn=SERVICE_ARN,
|
||||
region=AWS_REGION_US_EAST_1,
|
||||
launch_type="FARGATE",
|
||||
platform_family="Windows",
|
||||
platform_version="1.0.0",
|
||||
assign_public_ip=False,
|
||||
tags=[],
|
||||
)
|
||||
|
||||
ecs_client.audit_config = {
|
||||
"fargate_windows_latest_version": "1.0.0",
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.ecs.ecs_service.ECS",
|
||||
ecs_client,
|
||||
):
|
||||
from prowler.providers.aws.services.ecs.ecs_service_fargate_latest_platform_version.ecs_service_fargate_latest_platform_version import (
|
||||
ecs_service_fargate_latest_platform_version,
|
||||
)
|
||||
|
||||
check = ecs_service_fargate_latest_platform_version()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert result[0].status_extended == (
|
||||
f"ECS Service {SERVICE_NAME} is using latest FARGATE Windows version 1.0.0."
|
||||
)
|
||||
assert result[0].resource_id == SERVICE_NAME
|
||||
assert result[0].resource_arn == SERVICE_ARN
|
||||
|
||||
def test_service_linux_no_latest_version(self):
|
||||
ecs_client = mock.MagicMock
|
||||
ecs_client.services = {}
|
||||
ecs_client.services[SERVICE_ARN] = Service(
|
||||
name=SERVICE_NAME,
|
||||
arn=SERVICE_ARN,
|
||||
region=AWS_REGION_US_EAST_1,
|
||||
launch_type="FARGATE",
|
||||
platform_family="Linux",
|
||||
platform_version="1.2.0",
|
||||
assign_public_ip=False,
|
||||
tags=[],
|
||||
)
|
||||
|
||||
ecs_client.audit_config = {
|
||||
"fargate_linux_latest_version": "1.4.0",
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.ecs.ecs_service.ECS",
|
||||
ecs_client,
|
||||
):
|
||||
from prowler.providers.aws.services.ecs.ecs_service_fargate_latest_platform_version.ecs_service_fargate_latest_platform_version import (
|
||||
ecs_service_fargate_latest_platform_version,
|
||||
)
|
||||
|
||||
check = ecs_service_fargate_latest_platform_version()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert result[0].status_extended == (
|
||||
f"ECS Service {SERVICE_NAME} is not using latest FARGATE Linux version 1.4.0, currently using 1.2.0."
|
||||
)
|
||||
assert result[0].resource_id == SERVICE_NAME
|
||||
assert result[0].resource_arn == SERVICE_ARN
|
||||
|
||||
def test_service_windows_no_latest_version(self):
|
||||
ecs_client = mock.MagicMock
|
||||
ecs_client.services = {}
|
||||
ecs_client.services[SERVICE_ARN] = Service(
|
||||
name=SERVICE_NAME,
|
||||
arn=SERVICE_ARN,
|
||||
region=AWS_REGION_US_EAST_1,
|
||||
launch_type="FARGATE",
|
||||
platform_family="Windows",
|
||||
platform_version="0.9.0",
|
||||
assign_public_ip=False,
|
||||
tags=[],
|
||||
)
|
||||
|
||||
ecs_client.audit_config = {
|
||||
"fargate_windows_latest_version": "1.0.0",
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.ecs.ecs_service.ECS",
|
||||
ecs_client,
|
||||
):
|
||||
from prowler.providers.aws.services.ecs.ecs_service_fargate_latest_platform_version.ecs_service_fargate_latest_platform_version import (
|
||||
ecs_service_fargate_latest_platform_version,
|
||||
)
|
||||
|
||||
check = ecs_service_fargate_latest_platform_version()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert result[0].status_extended == (
|
||||
f"ECS Service {SERVICE_NAME} is not using latest FARGATE Windows version 1.0.0, currently using 0.9.0."
|
||||
)
|
||||
assert result[0].resource_id == SERVICE_NAME
|
||||
assert result[0].resource_arn == SERVICE_ARN
|
||||
@@ -44,7 +44,6 @@ def mock_make_api_call(self, operation_name, kwarg):
|
||||
{
|
||||
"serviceArn": "arn:aws:ecs:eu-west-1:123456789012:service/test_cluster_1/test_ecs_service",
|
||||
"serviceName": "test_ecs_service",
|
||||
"launchType": "EC2",
|
||||
"networkConfiguration": {
|
||||
"awsvpcConfiguration": {
|
||||
"subnets": ["subnet-12345678"],
|
||||
@@ -52,6 +51,9 @@ def mock_make_api_call(self, operation_name, kwarg):
|
||||
"assignPublicIp": "ENABLED",
|
||||
}
|
||||
},
|
||||
"launchType": "FARGATE",
|
||||
"platformVersion": "1.4.0",
|
||||
"platformFamily": "Linux",
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -218,3 +220,6 @@ class Test_ECS_Service:
|
||||
assert ecs.services[service_arn].region == AWS_REGION_EU_WEST_1
|
||||
assert ecs.services[service_arn].assign_public_ip
|
||||
assert ecs.services[service_arn].tags == []
|
||||
assert ecs.services[service_arn].launch_type == "FARGATE"
|
||||
assert ecs.services[service_arn].platform_version == "1.4.0"
|
||||
assert ecs.services[service_arn].platform_family == "Linux"
|
||||
|
||||
Reference in New Issue
Block a user