mirror of
https://github.com/ghndrx/prowler.git
synced 2026-02-10 23:05:05 +00:00
fix(iam_role_cross_service_confused_deputy_prevention): avoid service linked roles (#2249)
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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"]
|
||||
|
||||
Reference in New Issue
Block a user