mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-01-25 02:08:11 +00:00
chore(ssm): add trusted accounts variable to ssm check (#5118)
Co-authored-by: Sergio Garcia <38561120+sergargar@users.noreply.github.com>
This commit is contained in:
@@ -127,6 +127,7 @@ aws:
|
||||
]
|
||||
|
||||
# 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.
|
||||
# Multi account environment: Any additional trusted account number should be added as a space separated list, e.g.
|
||||
# trusted_account_ids : ["123456789012", "098765432109", "678901234567"]
|
||||
|
||||
@@ -43,6 +43,7 @@ aws:
|
||||
]
|
||||
|
||||
# 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.
|
||||
# Multi account environment: Any additional trusted account number should be added as a space separated list, e.g.
|
||||
# trusted_account_ids : ["123456789012", "098765432109", "678901234567"]
|
||||
|
||||
@@ -11,12 +11,25 @@ class ssm_documents_set_as_public(Check):
|
||||
report.resource_arn = document.arn
|
||||
report.resource_id = document.name
|
||||
report.resource_tags = document.tags
|
||||
if document.account_owners:
|
||||
report.status = "FAIL"
|
||||
report.status_extended = f"SSM Document {document.name} is public."
|
||||
else:
|
||||
trusted_account_ids = ssm_client.audit_config.get("trusted_account_ids", [])
|
||||
if ssm_client.audited_account not in trusted_account_ids:
|
||||
trusted_account_ids.append(ssm_client.audited_account)
|
||||
if not document.account_owners or document.account_owners == [
|
||||
ssm_client.audited_account
|
||||
]:
|
||||
report.status = "PASS"
|
||||
report.status_extended = f"SSM Document {document.name} is not public."
|
||||
elif document.account_owners == ["all"]:
|
||||
report.status = "FAIL"
|
||||
report.status_extended = f"SSM Document {document.name} is public."
|
||||
elif all(owner in trusted_account_ids for owner in document.account_owners):
|
||||
report.status = "PASS"
|
||||
report.status_extended = f"SSM Document {document.name} is shared to trusted AWS accounts: {', '.join(document.account_owners)}."
|
||||
elif not all(
|
||||
owner in trusted_account_ids for owner in document.account_owners
|
||||
):
|
||||
report.status = "FAIL"
|
||||
report.status_extended = f"SSM Document {document.name} is shared to non-trusted AWS accounts: {', '.join(document.account_owners)}."
|
||||
|
||||
findings.append(report)
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ aws:
|
||||
]
|
||||
|
||||
# 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.
|
||||
# Multi account environment: Any additional trusted account number should be added as a space separated list, e.g.
|
||||
# trusted_account_ids : ["123456789012", "098765432109", "678901234567"]
|
||||
|
||||
@@ -19,6 +19,7 @@ ec2_allowed_instance_owners:
|
||||
]
|
||||
|
||||
# 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.
|
||||
# Multi account environment: Any additional trusted account number should be added as a space separated list, e.g.
|
||||
# trusted_account_ids : ["123456789012", "098765432109", "678901234567"]
|
||||
|
||||
@@ -22,7 +22,7 @@ class Test_ssm_documents_set_as_public:
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
def test_document_public(self):
|
||||
def test_document_public_account_owners(self):
|
||||
ssm_client = mock.MagicMock
|
||||
document_name = "test-document"
|
||||
document_arn = f"arn:aws:ssm:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:document/{document_name}"
|
||||
@@ -48,6 +48,42 @@ class Test_ssm_documents_set_as_public:
|
||||
check = ssm_documents_set_as_public()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].region == AWS_REGION_US_EAST_1
|
||||
assert result[0].resource_id == document_name
|
||||
assert result[0].resource_arn == document_arn
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"SSM Document {document_name} is shared to non-trusted AWS accounts: 111111111111, 111111222222."
|
||||
)
|
||||
|
||||
def test_document_public_all_account_owners(self):
|
||||
ssm_client = mock.MagicMock
|
||||
document_name = "test-document"
|
||||
document_arn = f"arn:aws:ssm:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:document/{document_name}"
|
||||
ssm_client.audited_account = AWS_ACCOUNT_NUMBER
|
||||
ssm_client.documents = {
|
||||
document_name: Document(
|
||||
arn=document_arn,
|
||||
name=document_name,
|
||||
region=AWS_REGION_US_EAST_1,
|
||||
content="",
|
||||
account_owners=["all"],
|
||||
)
|
||||
}
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.ssm.ssm_service.SSM",
|
||||
new=ssm_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.ssm.ssm_documents_set_as_public.ssm_documents_set_as_public import (
|
||||
ssm_documents_set_as_public,
|
||||
)
|
||||
|
||||
check = ssm_documents_set_as_public()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].region == AWS_REGION_US_EAST_1
|
||||
assert result[0].resource_id == document_name
|
||||
@@ -57,6 +93,81 @@ class Test_ssm_documents_set_as_public:
|
||||
result[0].status_extended == f"SSM Document {document_name} is public."
|
||||
)
|
||||
|
||||
def test_document_public_to_other_trusted_AWS_accounts(self):
|
||||
ssm_client = mock.MagicMock
|
||||
document_name = "test-document"
|
||||
document_arn = f"arn:aws:ssm:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:document/{document_name}"
|
||||
ssm_client.audited_account = AWS_ACCOUNT_NUMBER
|
||||
ssm_client.documents = {
|
||||
document_name: Document(
|
||||
arn=document_arn,
|
||||
name=document_name,
|
||||
region=AWS_REGION_US_EAST_1,
|
||||
content="",
|
||||
account_owners=["111111111333", "111111222444"],
|
||||
)
|
||||
}
|
||||
ssm_client.audit_config = {
|
||||
"trusted_account_ids": ["111111111333", "111111222444"]
|
||||
}
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.ssm.ssm_service.SSM",
|
||||
new=ssm_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.ssm.ssm_documents_set_as_public.ssm_documents_set_as_public import (
|
||||
ssm_documents_set_as_public,
|
||||
)
|
||||
|
||||
check = ssm_documents_set_as_public()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].region == AWS_REGION_US_EAST_1
|
||||
assert result[0].resource_id == document_name
|
||||
assert result[0].resource_arn == document_arn
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"SSM Document {document_name} is shared to trusted AWS accounts: 111111111333, 111111222444."
|
||||
)
|
||||
|
||||
def test_document_public_to_self_account(self):
|
||||
ssm_client = mock.MagicMock
|
||||
document_name = "test-document"
|
||||
document_arn = f"arn:aws:ssm:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:document/{document_name}"
|
||||
ssm_client.audited_account = AWS_ACCOUNT_NUMBER
|
||||
ssm_client.documents = {
|
||||
document_name: Document(
|
||||
arn=document_arn,
|
||||
name=document_name,
|
||||
region=AWS_REGION_US_EAST_1,
|
||||
content="",
|
||||
account_owners=[AWS_ACCOUNT_NUMBER],
|
||||
)
|
||||
}
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.ssm.ssm_service.SSM",
|
||||
new=ssm_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.ssm.ssm_documents_set_as_public.ssm_documents_set_as_public import (
|
||||
ssm_documents_set_as_public,
|
||||
)
|
||||
|
||||
check = ssm_documents_set_as_public()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].region == AWS_REGION_US_EAST_1
|
||||
assert result[0].resource_id == document_name
|
||||
assert result[0].resource_arn == document_arn
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"SSM Document {document_name} is not public."
|
||||
)
|
||||
|
||||
def test_document_not_public(self):
|
||||
ssm_client = mock.MagicMock
|
||||
document_name = "test-document"
|
||||
|
||||
Reference in New Issue
Block a user