fix(iam_role_cross_service_confused_deputy_prevention): avoid service linked roles (#2249)

This commit is contained in:
Sergio Garcia
2023-04-21 10:42:05 +02:00
committed by GitHub
parent f8b382e480
commit d51cdc068b
2 changed files with 66 additions and 6 deletions

View File

@@ -6,15 +6,15 @@ class iam_role_cross_service_confused_deputy_prevention(Check):
def execute(self) -> Check_Report_AWS:
findings = []
for role in iam_client.roles:
# This check should only be performed against service roles
if role.is_service_role:
# This check should only be performed against service roles (avoid Service Linked Roles since the trust relationship cannot be changed)
if role.is_service_role and "aws-service-role" not in role.arn:
report = Check_Report_AWS(self.metadata())
report.region = iam_client.region
report.resource_arn = role.arn
report.resource_id = role.name
report.resource_tags = role.tags
report.status = "FAIL"
report.status_extended = f"IAM Service Role {role.name} prevents against a cross-service confused deputy attack"
report.status_extended = f"IAM Service Role {role.name} does not prevent against a cross-service confused deputy attack"
for statement in role.assume_role_policy["Statement"]:
if (
statement["Effect"] == "Allow"
@@ -59,7 +59,7 @@ class iam_role_cross_service_confused_deputy_prevention(Check):
)
):
report.status = "PASS"
report.status_extended = f"IAM Service Role {role.name} does not prevent against a cross-service confused deputy attack"
report.status_extended = f"IAM Service Role {role.name} prevents against a cross-service confused deputy attack"
break
findings.append(report)

View File

@@ -5,6 +5,7 @@ from boto3 import client, session
from moto import mock_iam
from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info
from prowler.providers.aws.services.iam.iam_service import Role
AWS_REGION = "us-east-1"
AWS_ACCOUNT_ID = "123456789012"
@@ -34,6 +35,65 @@ class Test_iam_role_cross_service_confused_deputy_prevention:
return audit_info
@mock_iam
def test_no_roles(self):
from prowler.providers.aws.services.iam.iam_service import IAM
current_audit_info = self.set_mocked_audit_info()
current_audit_info.audited_account = AWS_ACCOUNT_ID
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=current_audit_info,
), mock.patch(
"prowler.providers.aws.services.iam.iam_role_cross_service_confused_deputy_prevention.iam_role_cross_service_confused_deputy_prevention.iam_client",
new=IAM(current_audit_info),
):
# Test Check
from prowler.providers.aws.services.iam.iam_role_cross_service_confused_deputy_prevention.iam_role_cross_service_confused_deputy_prevention import (
iam_role_cross_service_confused_deputy_prevention,
)
check = iam_role_cross_service_confused_deputy_prevention()
result = check.execute()
assert len(result) == 0
@mock_iam
def test_only_aws_service_linked_roles(self):
iam_client = mock.MagicMock
iam_client.roles = []
iam_client.roles.append(
Role(
name="AWSServiceRoleForAmazonGuardDuty",
arn="arn:aws:iam::106908755756:role/aws-service-role/guardduty.amazonaws.com/AWSServiceRoleForAmazonGuardDuty",
assume_role_policy={
"Version": "2008-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {"Service": "ec2.amazonaws.com"},
"Action": "sts:AssumeRole",
}
],
},
is_service_role=True,
)
)
current_audit_info = self.set_mocked_audit_info()
current_audit_info.audited_account = AWS_ACCOUNT_ID
with mock.patch(
"prowler.providers.aws.services.iam.iam_service.IAM",
iam_client,
):
# Test Check
from prowler.providers.aws.services.iam.iam_role_cross_service_confused_deputy_prevention.iam_role_cross_service_confused_deputy_prevention import (
iam_role_cross_service_confused_deputy_prevention,
)
check = iam_role_cross_service_confused_deputy_prevention()
result = check.execute()
assert len(result) == 0
@mock_iam
def test_iam_service_role_without_cross_service_confused_deputy_prevention(self):
iam_client = client("iam", region_name=AWS_REGION)
@@ -74,7 +134,7 @@ class Test_iam_role_cross_service_confused_deputy_prevention:
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== "IAM Service Role test prevents against a cross-service confused deputy attack"
== "IAM Service Role test does not prevent against a cross-service confused deputy attack"
)
assert result[0].resource_id == "test"
assert result[0].resource_arn == response["Role"]["Arn"]
@@ -122,7 +182,7 @@ class Test_iam_role_cross_service_confused_deputy_prevention:
assert result[0].status == "PASS"
assert (
result[0].status_extended
== "IAM Service Role test does not prevent against a cross-service confused deputy attack"
== "IAM Service Role test prevents against a cross-service confused deputy attack"
)
assert result[0].resource_id == "test"
assert result[0].resource_arn == response["Role"]["Arn"]