feat(ec2): add new fixer ec2_ebs_public_snapshot_fixer (#5825)

Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
This commit is contained in:
Daniel Barranquero
2024-11-21 17:40:28 +01:00
committed by GitHub
parent 24fc86cbb3
commit 00054b5cd9
2 changed files with 134 additions and 0 deletions
@@ -0,0 +1,41 @@
from prowler.lib.logger import logger
from prowler.providers.aws.services.ec2.ec2_client import ec2_client
def fixer(resource_id: str, region: str) -> bool:
"""
Modify the attributes of an EBS snapshot to remove public access.
Specifically, this fixer removes the 'all' value from the 'createVolumePermission' attribute to
prevent the snapshot from being publicly accessible.
Requires the ec2:ModifySnapshotAttribute permission.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "ec2:ModifySnapshotAttribute",
"Resource": "*"
}
]
}
Args:
resource_id (str): The snapshot identifier.
region (str): AWS region where the snapshot exists.
Returns:
bool: True if the operation is successful (public access is removed), False otherwise.
"""
try:
regional_client = ec2_client.regional_clients[region]
regional_client.modify_snapshot_attribute(
SnapshotId=resource_id,
Attribute="createVolumePermission",
OperationType="remove",
GroupNames=["all"],
)
except Exception as error:
logger.error(
f"{region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
return False
else:
return True
@@ -0,0 +1,93 @@
from unittest import mock
import botocore
import botocore.client
from moto import mock_aws
from tests.providers.aws.utils import (
AWS_REGION_EU_WEST_1,
AWS_REGION_US_EAST_1,
set_mocked_aws_provider,
)
mock_make_api_call = botocore.client.BaseClient._make_api_call
def mock_make_api_call_public_snapshot(self, operation_name, kwarg):
if operation_name == "ModifySnapshotAttribute":
return {
"SnapshotId": "testsnap",
"Attribute": "createVolumePermission",
"OperationType": "remove",
"GroupNames": ["all"],
}
return mock_make_api_call(self, operation_name, kwarg)
def mock_make_api_call_error(self, operation_name, kwarg):
if operation_name == "ModifySnapshotAttribute":
raise botocore.exceptions.ClientError(
{
"Error": {
"Code": "UnauthorizedOperation",
"Message": "You are not authorized to perform this operation.",
}
},
operation_name,
)
return mock_make_api_call(self, operation_name, kwarg)
class Test_ec2_ebs_public_snapshot_fixer_test:
@mock_aws
def test_ebs_public_snapshot(self):
with mock.patch(
"botocore.client.BaseClient._make_api_call",
new=mock_make_api_call_public_snapshot,
):
from prowler.providers.aws.services.ec2.ec2_service import EC2
aws_provider = set_mocked_aws_provider(
[AWS_REGION_EU_WEST_1, 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.ec2.ec2_ebs_public_snapshot.ec2_ebs_public_snapshot_fixer.ec2_client",
new=EC2(aws_provider),
):
# Test Check
from prowler.providers.aws.services.ec2.ec2_ebs_public_snapshot.ec2_ebs_public_snapshot_fixer import (
fixer,
)
assert fixer("testsnap", AWS_REGION_US_EAST_1)
@mock_aws
def test_ebs_public_snapshot_error(self):
with mock.patch(
"botocore.client.BaseClient._make_api_call", new=mock_make_api_call_error
):
from prowler.providers.aws.services.ec2.ec2_service import EC2
aws_provider = set_mocked_aws_provider(
[AWS_REGION_EU_WEST_1, 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.ec2.ec2_ebs_public_snapshot.ec2_ebs_public_snapshot_fixer.ec2_client",
new=EC2(aws_provider),
):
# Test Check
from prowler.providers.aws.services.ec2.ec2_ebs_public_snapshot.ec2_ebs_public_snapshot_fixer import (
fixer,
)
assert not fixer("testsnap", AWS_REGION_US_EAST_1)