diff --git a/prowler/providers/aws/lib/policy_condition_parser/policy_condition_parser.py b/prowler/providers/aws/lib/policy_condition_parser/policy_condition_parser.py index 99a40406..020aedc5 100644 --- a/prowler/providers/aws/lib/policy_condition_parser/policy_condition_parser.py +++ b/prowler/providers/aws/lib/policy_condition_parser/policy_condition_parser.py @@ -56,12 +56,15 @@ def is_account_only_allowed_in_condition( ): # if there is an arn/account without the source account -> we do not consider it safe # here by default we assume is true and look for false entries - is_condition_valid = True + is_condition_key_restrictive = True for item in condition_statement[condition_operator][value]: if source_account not in item: - is_condition_valid = False + is_condition_key_restrictive = False break + if is_condition_key_restrictive: + is_condition_valid = True + # value is a string elif isinstance( condition_statement[condition_operator][value], diff --git a/tests/providers/aws/lib/policy_condition_parser/policy_condition_parser_test.py b/tests/providers/aws/lib/policy_condition_parser/policy_condition_parser_test.py index 14d45471..4e8e71cc 100644 --- a/tests/providers/aws/lib/policy_condition_parser/policy_condition_parser_test.py +++ b/tests/providers/aws/lib/policy_condition_parser/policy_condition_parser_test.py @@ -1282,3 +1282,75 @@ class Test_policy_condition_parser: assert not is_account_only_allowed_in_condition( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) + + def test_condition_parser_two_lists_unrestrictive(self): + condition_statement = { + "StringLike": { + "AWS:ResourceAccount": [ + TRUSTED_AWS_ACCOUNT_NUMBER, + NON_TRUSTED_AWS_ACCOUNT_NUMBER, + ] + }, + "ArnLike": { + "AWS:SourceArn": [ + f"arn:aws:cloudtrail:*:{TRUSTED_AWS_ACCOUNT_NUMBER}:trail/*", + f"arn:aws:cloudtrail:*:{NON_TRUSTED_AWS_ACCOUNT_NUMBER}:trail/*", + ] + }, + } + assert not is_account_only_allowed_in_condition( + condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER + ) + + def test_condition_parser_two_lists_both_restrictive(self): + condition_statement = { + "StringLike": { + "AWS:ResourceAccount": [ + TRUSTED_AWS_ACCOUNT_NUMBER, + ] + }, + "ArnLike": { + "AWS:SourceArn": [ + f"arn:aws:cloudtrail:*:{TRUSTED_AWS_ACCOUNT_NUMBER}:trail/*", + ] + }, + } + assert is_account_only_allowed_in_condition( + condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER + ) + + def test_condition_parser_two_lists_first_restrictive(self): + condition_statement = { + "StringLike": { + "AWS:ResourceAccount": [ + TRUSTED_AWS_ACCOUNT_NUMBER, + ] + }, + "ArnLike": { + "AWS:SourceArn": [ + f"arn:aws:cloudtrail:*:{TRUSTED_AWS_ACCOUNT_NUMBER}:trail/*", + f"arn:aws:cloudtrail:*:{NON_TRUSTED_AWS_ACCOUNT_NUMBER}:trail/*", + ] + }, + } + assert is_account_only_allowed_in_condition( + condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER + ) + + def test_condition_parser_two_lists_second_restrictive(self): + condition_statement = { + "StringLike": { + "AWS:ResourceAccount": [ + TRUSTED_AWS_ACCOUNT_NUMBER, + NON_TRUSTED_AWS_ACCOUNT_NUMBER, + ] + }, + "ArnLike": { + "AWS:SourceArn": [ + f"arn:aws:cloudtrail:*:{TRUSTED_AWS_ACCOUNT_NUMBER}:trail/*", + ] + }, + } + assert is_account_only_allowed_in_condition( + condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER + )