fix(iam_role_cross_service_confused_deputy_prevention): add ResourceAccount and PrincipalAccount conditions (#2689)

This commit is contained in:
Sergio Garcia
2023-08-09 10:41:48 +02:00
committed by GitHub
parent 887cac1264
commit 36e095c830
4 changed files with 219 additions and 41 deletions

View File

@@ -32,6 +32,32 @@ class Test_policy_condition_parser:
condition_statement, AWS_ACCOUNT_NUMBER
)
def test_condition_parser_string_like_aws_SourceAccount_list(self):
condition_statement = {"StringLike": {"aws:SourceAccount": ["123456789012"]}}
assert is_account_only_allowed_in_condition(
condition_statement, AWS_ACCOUNT_NUMBER
)
def test_condition_parser_string_like_aws_SourceAccount_str(self):
condition_statement = {"StringLike": {"aws:SourceAccount": "123456789012"}}
assert is_account_only_allowed_in_condition(
condition_statement, AWS_ACCOUNT_NUMBER
)
def test_condition_parser_string_like_aws_SourceAccount_list_not_valid(self):
condition_statement = {
"StringLike": {"aws:SourceAccount": ["123456789012", "111222333444"]}
}
assert not is_account_only_allowed_in_condition(
condition_statement, AWS_ACCOUNT_NUMBER
)
def test_condition_parser_string_like_aws_SourceAccount_str_not_valid(self):
condition_statement = {"StringLike": {"aws:SourceAccount": "111222333444"}}
assert not is_account_only_allowed_in_condition(
condition_statement, AWS_ACCOUNT_NUMBER
)
def test_condition_parser_string_equals_s3_ResourceAccount_list(self):
condition_statement = {"StringEquals": {"s3:ResourceAccount": ["123456789012"]}}
assert is_account_only_allowed_in_condition(
@@ -86,6 +112,32 @@ class Test_policy_condition_parser:
condition_statement, AWS_ACCOUNT_NUMBER
)
def test_condition_parser_string_like_aws_PrincipalAccount_list(self):
condition_statement = {"StringLike": {"aws:PrincipalAccount": ["123456789012"]}}
assert is_account_only_allowed_in_condition(
condition_statement, AWS_ACCOUNT_NUMBER
)
def test_condition_parser_string_like_aws_PrincipalAccount_str(self):
condition_statement = {"StringLike": {"aws:PrincipalAccount": "123456789012"}}
assert is_account_only_allowed_in_condition(
condition_statement, AWS_ACCOUNT_NUMBER
)
def test_condition_parser_string_like_aws_PrincipalAccount_list_not_valid(self):
condition_statement = {
"StringLike": {"aws:PrincipalAccount": ["123456789012", "111222333444"]}
}
assert not is_account_only_allowed_in_condition(
condition_statement, AWS_ACCOUNT_NUMBER
)
def test_condition_parser_string_like_aws_PrincipalAccount_str_not_valid(self):
condition_statement = {"StringLike": {"aws:PrincipalAccount": "111222333444"}}
assert not is_account_only_allowed_in_condition(
condition_statement, AWS_ACCOUNT_NUMBER
)
def test_condition_parser_arn_like_aws_SourceArn_list(self):
condition_statement = {
"ArnLike": {"aws:SourceArn": ["arn:aws:cloudtrail:*:123456789012:trail/*"]}
@@ -365,3 +417,57 @@ class Test_policy_condition_parser:
assert not is_account_only_allowed_in_condition(
condition_statement, AWS_ACCOUNT_NUMBER
)
def test_condition_parser_string_equals_aws_ResourceAccount_list(self):
condition_statement = {
"StringEquals": {"aws:ResourceAccount": ["123456789012"]}
}
assert is_account_only_allowed_in_condition(
condition_statement, AWS_ACCOUNT_NUMBER
)
def test_condition_parser_string_equals_aws_ResourceAccount_str(self):
condition_statement = {"StringEquals": {"aws:ResourceAccount": "123456789012"}}
assert is_account_only_allowed_in_condition(
condition_statement, AWS_ACCOUNT_NUMBER
)
def test_condition_parser_string_equals_aws_ResourceAccount_list_not_valid(self):
condition_statement = {
"StringEquals": {"aws:ResourceAccount": ["123456789012", "111222333444"]}
}
assert not is_account_only_allowed_in_condition(
condition_statement, AWS_ACCOUNT_NUMBER
)
def test_condition_parser_string_equals_aws_ResourceAccount_str_not_valid(self):
condition_statement = {"StringEquals": {"aws:ResourceAccount": "111222333444"}}
assert not is_account_only_allowed_in_condition(
condition_statement, AWS_ACCOUNT_NUMBER
)
def test_condition_parser_string_like_aws_ResourceAccount_list(self):
condition_statement = {"StringLike": {"aws:ResourceAccount": ["123456789012"]}}
assert is_account_only_allowed_in_condition(
condition_statement, AWS_ACCOUNT_NUMBER
)
def test_condition_parser_string_like_aws_ResourceAccount_str(self):
condition_statement = {"StringLike": {"aws:ResourceAccount": "123456789012"}}
assert is_account_only_allowed_in_condition(
condition_statement, AWS_ACCOUNT_NUMBER
)
def test_condition_parser_string_like_aws_ResourceAccount_list_not_valid(self):
condition_statement = {
"StringLike": {"aws:ResourceAccount": ["123456789012", "111222333444"]}
}
assert not is_account_only_allowed_in_condition(
condition_statement, AWS_ACCOUNT_NUMBER
)
def test_condition_parser_string_like_aws_ResourceAccount_str_not_valid(self):
condition_statement = {"StringLike": {"aws:ResourceAccount": "111222333444"}}
assert not is_account_only_allowed_in_condition(
condition_statement, AWS_ACCOUNT_NUMBER
)

View File

@@ -249,3 +249,103 @@ class Test_iam_role_cross_service_confused_deputy_prevention:
)
assert result[0].resource_id == "test"
assert result[0].resource_arn == response["Role"]["Arn"]
@mock_iam
def test_iam_service_role_with_cross_service_confused_deputy_prevention_PrincipalAccount(
self,
):
iam_client = client("iam", region_name=AWS_REGION)
policy_document = {
"Version": "2008-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {"Service": "workspaces.amazonaws.com"},
"Action": "sts:AssumeRole",
"Condition": {
"StringLike": {"aws:PrincipalAccount": [AWS_ACCOUNT_ID]}
},
}
],
}
response = iam_client.create_role(
RoleName="test",
AssumeRolePolicyDocument=dumps(policy_document),
)
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) == 1
assert result[0].status == "PASS"
assert (
result[0].status_extended
== "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"]
@mock_iam
def test_iam_service_role_with_cross_service_confused_deputy_prevention_ResourceAccount(
self,
):
iam_client = client("iam", region_name=AWS_REGION)
policy_document = {
"Version": "2008-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {"Service": "workspaces.amazonaws.com"},
"Action": "sts:AssumeRole",
"Condition": {
"StringLike": {"aws:ResourceAccount": [AWS_ACCOUNT_ID]}
},
}
],
}
response = iam_client.create_role(
RoleName="test",
AssumeRolePolicyDocument=dumps(policy_document),
)
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) == 1
assert result[0].status == "PASS"
assert (
result[0].status_extended
== "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"]