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 020aedc5..7dde2bdd 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 @@ -1,8 +1,11 @@ -def is_account_only_allowed_in_condition( - condition_statement: dict, source_account: str +def is_condition_block_restrictive( + condition_statement: dict, source_account: str, is_cross_account_allowed=False ): """ - is_account_only_allowed_in_condition parses the IAM Condition policy block and returns True if the source_account passed as argument is within, False if not. + is_condition_block_restrictive parses the IAM Condition policy block and, by default, returns True if the source_account passed as argument is within, False if not. + + If argument is_cross_account_allowed is True it tests if the Condition block includes any of the operators allowlisted returning True if does, False if not. + @param condition_statement: dict with an IAM Condition block, e.g.: { @@ -54,13 +57,16 @@ def is_account_only_allowed_in_condition( condition_statement[condition_operator][value], list, ): - # 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_key_restrictive = True - for item in condition_statement[condition_operator][value]: - if source_account not in item: - is_condition_key_restrictive = False - break + # if cross account is not allowed check for each condition block looking for accounts + # different than default + if not is_cross_account_allowed: + # 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 + for item in condition_statement[condition_operator][value]: + if source_account not in item: + is_condition_key_restrictive = False + break if is_condition_key_restrictive: is_condition_valid = True @@ -70,10 +76,13 @@ def is_account_only_allowed_in_condition( condition_statement[condition_operator][value], str, ): - if ( - source_account - in condition_statement[condition_operator][value] - ): + if is_cross_account_allowed: is_condition_valid = True + else: + if ( + source_account + in condition_statement[condition_operator][value] + ): + is_condition_valid = True return is_condition_valid diff --git a/prowler/providers/aws/services/iam/iam_role_cross_service_confused_deputy_prevention/iam_role_cross_service_confused_deputy_prevention.py b/prowler/providers/aws/services/iam/iam_role_cross_service_confused_deputy_prevention/iam_role_cross_service_confused_deputy_prevention.py index c2fa7b91..3fd7739e 100644 --- a/prowler/providers/aws/services/iam/iam_role_cross_service_confused_deputy_prevention/iam_role_cross_service_confused_deputy_prevention.py +++ b/prowler/providers/aws/services/iam/iam_role_cross_service_confused_deputy_prevention/iam_role_cross_service_confused_deputy_prevention.py @@ -1,6 +1,6 @@ from prowler.lib.check.models import Check, Check_Report_AWS from prowler.providers.aws.lib.policy_condition_parser.policy_condition_parser import ( - is_account_only_allowed_in_condition, + is_condition_block_restrictive, ) from prowler.providers.aws.services.iam.iam_client import iam_client @@ -30,7 +30,7 @@ class iam_role_cross_service_confused_deputy_prevention(Check): and "Service" in statement["Principal"] # Check to see if the appropriate condition statements have been implemented and "Condition" in statement - and is_account_only_allowed_in_condition( + and is_condition_block_restrictive( statement["Condition"], iam_client.audited_account ) ): diff --git a/prowler/providers/aws/services/sns/sns_topics_not_publicly_accessible/sns_topics_not_publicly_accessible.py b/prowler/providers/aws/services/sns/sns_topics_not_publicly_accessible/sns_topics_not_publicly_accessible.py index bec81d1b..91f24482 100644 --- a/prowler/providers/aws/services/sns/sns_topics_not_publicly_accessible/sns_topics_not_publicly_accessible.py +++ b/prowler/providers/aws/services/sns/sns_topics_not_publicly_accessible/sns_topics_not_publicly_accessible.py @@ -1,6 +1,6 @@ from prowler.lib.check.models import Check, Check_Report_AWS from prowler.providers.aws.lib.policy_condition_parser.policy_condition_parser import ( - is_account_only_allowed_in_condition, + is_condition_block_restrictive, ) from prowler.providers.aws.services.sns.sns_client import sns_client @@ -35,7 +35,7 @@ class sns_topics_not_publicly_accessible(Check): ): if ( "Condition" in statement - and is_account_only_allowed_in_condition( + and is_condition_block_restrictive( statement["Condition"], sns_client.audited_account ) ): diff --git a/prowler/providers/aws/services/sqs/sqs_queues_not_publicly_accessible/sqs_queues_not_publicly_accessible.py b/prowler/providers/aws/services/sqs/sqs_queues_not_publicly_accessible/sqs_queues_not_publicly_accessible.py index f360b7bc..9207d6c2 100644 --- a/prowler/providers/aws/services/sqs/sqs_queues_not_publicly_accessible/sqs_queues_not_publicly_accessible.py +++ b/prowler/providers/aws/services/sqs/sqs_queues_not_publicly_accessible/sqs_queues_not_publicly_accessible.py @@ -1,6 +1,6 @@ from prowler.lib.check.models import Check, Check_Report_AWS from prowler.providers.aws.lib.policy_condition_parser.policy_condition_parser import ( - is_account_only_allowed_in_condition, + is_condition_block_restrictive, ) from prowler.providers.aws.services.sqs.sqs_client import sqs_client @@ -32,8 +32,10 @@ class sqs_queues_not_publicly_accessible(Check): ) ): if "Condition" in statement: - if is_account_only_allowed_in_condition( - statement["Condition"], sqs_client.audited_account + if is_condition_block_restrictive( + statement["Condition"], + sqs_client.audited_account, + True, ): report.status_extended = f"SQS queue {queue.id} is not public because its policy only allows access from the same account." else: diff --git a/prowler/providers/aws/services/vpc/vpc_endpoint_connections_trust_boundaries/vpc_endpoint_connections_trust_boundaries.py b/prowler/providers/aws/services/vpc/vpc_endpoint_connections_trust_boundaries/vpc_endpoint_connections_trust_boundaries.py index 311a4942..0884c2a5 100644 --- a/prowler/providers/aws/services/vpc/vpc_endpoint_connections_trust_boundaries/vpc_endpoint_connections_trust_boundaries.py +++ b/prowler/providers/aws/services/vpc/vpc_endpoint_connections_trust_boundaries/vpc_endpoint_connections_trust_boundaries.py @@ -2,7 +2,7 @@ from re import compile from prowler.lib.check.models import Check, Check_Report_AWS from prowler.providers.aws.lib.policy_condition_parser.policy_condition_parser import ( - is_account_only_allowed_in_condition, + is_condition_block_restrictive, ) from prowler.providers.aws.services.vpc.vpc_client import vpc_client @@ -35,7 +35,7 @@ class vpc_endpoint_connections_trust_boundaries(Check): if "Condition" in statement: for account_id in trusted_account_ids: - if is_account_only_allowed_in_condition( + if is_condition_block_restrictive( statement["Condition"], account_id ): access_from_trusted_accounts = True @@ -70,7 +70,7 @@ class vpc_endpoint_connections_trust_boundaries(Check): access_from_trusted_accounts = False if "Condition" in statement: for account_id in trusted_account_ids: - if is_account_only_allowed_in_condition( + if is_condition_block_restrictive( statement["Condition"], account_id ): access_from_trusted_accounts = True @@ -102,7 +102,7 @@ class vpc_endpoint_connections_trust_boundaries(Check): if "Condition" in statement: for account_id in trusted_account_ids: - if is_account_only_allowed_in_condition( + if is_condition_block_restrictive( statement["Condition"], account_id ): access_from_trusted_accounts = True 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 4e8e71cc..c7b000b5 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 @@ -1,5 +1,5 @@ from prowler.providers.aws.lib.policy_condition_parser.policy_condition_parser import ( - is_account_only_allowed_in_condition, + is_condition_block_restrictive, ) TRUSTED_AWS_ACCOUNT_NUMBER = "123456789012" @@ -12,7 +12,7 @@ class Test_policy_condition_parser: condition_statement = { "StringEquals": {"aws:SourceAccount": [TRUSTED_AWS_ACCOUNT_NUMBER]} } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -25,7 +25,7 @@ class Test_policy_condition_parser: ] } } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -33,7 +33,7 @@ class Test_policy_condition_parser: condition_statement = { "StringEquals": {"aws:SourceAccount": TRUSTED_AWS_ACCOUNT_NUMBER} } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -41,7 +41,7 @@ class Test_policy_condition_parser: condition_statement = { "StringEquals": {"aws:SourceAccount": NON_TRUSTED_AWS_ACCOUNT_NUMBER} } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -49,7 +49,7 @@ class Test_policy_condition_parser: condition_statement = { "StringLike": {"aws:SourceAccount": [TRUSTED_AWS_ACCOUNT_NUMBER]} } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -62,7 +62,7 @@ class Test_policy_condition_parser: ] } } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -70,7 +70,7 @@ class Test_policy_condition_parser: condition_statement = { "StringLike": {"aws:SourceAccount": TRUSTED_AWS_ACCOUNT_NUMBER} } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -78,7 +78,7 @@ class Test_policy_condition_parser: condition_statement = { "StringLike": {"aws:SourceAccount": NON_TRUSTED_AWS_ACCOUNT_NUMBER} } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -86,7 +86,7 @@ class Test_policy_condition_parser: condition_statement = { "StringEquals": {"aws:SourceOwner": TRUSTED_AWS_ACCOUNT_NUMBER} } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -94,7 +94,7 @@ class Test_policy_condition_parser: condition_statement = { "StringEquals": {"aws:SourceOwner": NON_TRUSTED_AWS_ACCOUNT_NUMBER} } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -102,7 +102,7 @@ class Test_policy_condition_parser: condition_statement = { "StringEquals": {"aws:SourceOwner": [TRUSTED_AWS_ACCOUNT_NUMBER]} } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -115,7 +115,7 @@ class Test_policy_condition_parser: ] } } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -123,7 +123,7 @@ class Test_policy_condition_parser: condition_statement = { "StringLike": {"aws:SourceOwner": [TRUSTED_AWS_ACCOUNT_NUMBER]} } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -136,7 +136,7 @@ class Test_policy_condition_parser: ] } } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -144,7 +144,7 @@ class Test_policy_condition_parser: condition_statement = { "StringLike": {"aws:SourceOwner": TRUSTED_AWS_ACCOUNT_NUMBER} } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -152,7 +152,7 @@ class Test_policy_condition_parser: condition_statement = { "StringLike": {"aws:SourceOwner": NON_TRUSTED_AWS_ACCOUNT_NUMBER} } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -160,7 +160,7 @@ class Test_policy_condition_parser: condition_statement = { "StringEquals": {"s3:ResourceAccount": [TRUSTED_AWS_ACCOUNT_NUMBER]} } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -173,7 +173,7 @@ class Test_policy_condition_parser: ] } } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -181,7 +181,7 @@ class Test_policy_condition_parser: condition_statement = { "StringEquals": {"s3:ResourceAccount": TRUSTED_AWS_ACCOUNT_NUMBER} } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -189,7 +189,7 @@ class Test_policy_condition_parser: condition_statement = { "StringEquals": {"s3:ResourceAccount": NON_TRUSTED_AWS_ACCOUNT_NUMBER} } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -197,7 +197,7 @@ class Test_policy_condition_parser: condition_statement = { "StringEquals": {"aws:PrincipalAccount": [TRUSTED_AWS_ACCOUNT_NUMBER]} } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -210,7 +210,7 @@ class Test_policy_condition_parser: ] } } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -218,7 +218,7 @@ class Test_policy_condition_parser: condition_statement = { "StringEquals": {"aws:PrincipalAccount": TRUSTED_AWS_ACCOUNT_NUMBER} } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -226,7 +226,7 @@ class Test_policy_condition_parser: condition_statement = { "StringEquals": {"aws:PrincipalAccount": NON_TRUSTED_AWS_ACCOUNT_NUMBER} } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -236,7 +236,7 @@ class Test_policy_condition_parser: "aws:SourceArn": f"arn:aws:cloudtrail:*:{TRUSTED_AWS_ACCOUNT_NUMBER}:trail/*" } } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -246,7 +246,7 @@ class Test_policy_condition_parser: "aws:SourceArn": f"arn:aws:cloudtrail:*:{NON_TRUSTED_AWS_ACCOUNT_NUMBER}:trail/*" } } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -254,7 +254,7 @@ class Test_policy_condition_parser: condition_statement = { "StringLike": {"aws:PrincipalAccount": [TRUSTED_AWS_ACCOUNT_NUMBER]} } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -267,7 +267,7 @@ class Test_policy_condition_parser: ] } } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -275,7 +275,7 @@ class Test_policy_condition_parser: condition_statement = { "StringLike": {"aws:PrincipalAccount": TRUSTED_AWS_ACCOUNT_NUMBER} } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -283,7 +283,7 @@ class Test_policy_condition_parser: condition_statement = { "StringLike": {"aws:PrincipalAccount": NON_TRUSTED_AWS_ACCOUNT_NUMBER} } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -296,7 +296,7 @@ class Test_policy_condition_parser: } } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -310,7 +310,7 @@ class Test_policy_condition_parser: } } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -321,7 +321,7 @@ class Test_policy_condition_parser: } } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -332,7 +332,7 @@ class Test_policy_condition_parser: } } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -345,7 +345,7 @@ class Test_policy_condition_parser: } } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -359,7 +359,7 @@ class Test_policy_condition_parser: } } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -370,7 +370,7 @@ class Test_policy_condition_parser: } } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -381,7 +381,7 @@ class Test_policy_condition_parser: } } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -394,7 +394,7 @@ class Test_policy_condition_parser: } } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -408,7 +408,7 @@ class Test_policy_condition_parser: } } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -419,7 +419,7 @@ class Test_policy_condition_parser: } } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -430,7 +430,7 @@ class Test_policy_condition_parser: } } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -443,7 +443,7 @@ class Test_policy_condition_parser: } } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -457,7 +457,7 @@ class Test_policy_condition_parser: } } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -468,7 +468,7 @@ class Test_policy_condition_parser: } } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -479,7 +479,7 @@ class Test_policy_condition_parser: } } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -492,7 +492,7 @@ class Test_policy_condition_parser: } } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -506,7 +506,7 @@ class Test_policy_condition_parser: } } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -517,7 +517,7 @@ class Test_policy_condition_parser: } } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -528,7 +528,7 @@ class Test_policy_condition_parser: } } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -541,7 +541,7 @@ class Test_policy_condition_parser: } } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -555,7 +555,7 @@ class Test_policy_condition_parser: } } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -566,7 +566,7 @@ class Test_policy_condition_parser: } } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -577,7 +577,7 @@ class Test_policy_condition_parser: } } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -585,7 +585,7 @@ class Test_policy_condition_parser: condition_statement = { "StringEquals": {"aws:ResourceAccount": [TRUSTED_AWS_ACCOUNT_NUMBER]} } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -598,7 +598,7 @@ class Test_policy_condition_parser: ] } } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -606,7 +606,7 @@ class Test_policy_condition_parser: condition_statement = { "StringEquals": {"aws:ResourceAccount": TRUSTED_AWS_ACCOUNT_NUMBER} } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -614,7 +614,7 @@ class Test_policy_condition_parser: condition_statement = { "StringEquals": {"aws:ResourceAccount": NON_TRUSTED_AWS_ACCOUNT_NUMBER} } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -622,7 +622,7 @@ class Test_policy_condition_parser: condition_statement = { "StringLike": {"aws:ResourceAccount": [TRUSTED_AWS_ACCOUNT_NUMBER]} } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -635,7 +635,7 @@ class Test_policy_condition_parser: ] } } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -643,7 +643,7 @@ class Test_policy_condition_parser: condition_statement = { "StringLike": {"aws:ResourceAccount": TRUSTED_AWS_ACCOUNT_NUMBER} } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -651,7 +651,7 @@ class Test_policy_condition_parser: condition_statement = { "StringLike": {"aws:ResourceAccount": NON_TRUSTED_AWS_ACCOUNT_NUMBER} } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -660,7 +660,7 @@ class Test_policy_condition_parser: condition_statement = { "StringEquals": {"AWS:SourceAccount": [TRUSTED_AWS_ACCOUNT_NUMBER]} } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -673,7 +673,7 @@ class Test_policy_condition_parser: ] } } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -681,7 +681,7 @@ class Test_policy_condition_parser: condition_statement = { "StringEquals": {"AWS:SourceAccount": TRUSTED_AWS_ACCOUNT_NUMBER} } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -689,7 +689,7 @@ class Test_policy_condition_parser: condition_statement = { "StringEquals": {"AWS:SourceAccount": NON_TRUSTED_AWS_ACCOUNT_NUMBER} } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -697,7 +697,7 @@ class Test_policy_condition_parser: condition_statement = { "StringLike": {"AWS:SourceAccount": [TRUSTED_AWS_ACCOUNT_NUMBER]} } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -710,7 +710,7 @@ class Test_policy_condition_parser: ] } } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -718,7 +718,7 @@ class Test_policy_condition_parser: condition_statement = { "StringLike": {"AWS:SourceAccount": TRUSTED_AWS_ACCOUNT_NUMBER} } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -726,7 +726,7 @@ class Test_policy_condition_parser: condition_statement = { "StringLike": {"AWS:SourceAccount": NON_TRUSTED_AWS_ACCOUNT_NUMBER} } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -734,7 +734,7 @@ class Test_policy_condition_parser: condition_statement = { "StringEquals": {"AWS:SourceOwner": TRUSTED_AWS_ACCOUNT_NUMBER} } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -742,7 +742,7 @@ class Test_policy_condition_parser: condition_statement = { "StringEquals": {"AWS:SourceOwner": NON_TRUSTED_AWS_ACCOUNT_NUMBER} } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -750,7 +750,7 @@ class Test_policy_condition_parser: condition_statement = { "StringEquals": {"AWS:SourceOwner": [TRUSTED_AWS_ACCOUNT_NUMBER]} } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -763,7 +763,7 @@ class Test_policy_condition_parser: ] } } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -771,7 +771,7 @@ class Test_policy_condition_parser: condition_statement = { "StringLike": {"AWS:SourceOwner": [TRUSTED_AWS_ACCOUNT_NUMBER]} } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -784,7 +784,7 @@ class Test_policy_condition_parser: ] } } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -792,7 +792,7 @@ class Test_policy_condition_parser: condition_statement = { "StringLike": {"AWS:SourceOwner": TRUSTED_AWS_ACCOUNT_NUMBER} } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -800,7 +800,7 @@ class Test_policy_condition_parser: condition_statement = { "StringLike": {"AWS:SourceOwner": NON_TRUSTED_AWS_ACCOUNT_NUMBER} } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -808,7 +808,7 @@ class Test_policy_condition_parser: condition_statement = { "StringEquals": {"S3:ResourceAccount": [TRUSTED_AWS_ACCOUNT_NUMBER]} } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -821,7 +821,7 @@ class Test_policy_condition_parser: ] } } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -829,7 +829,7 @@ class Test_policy_condition_parser: condition_statement = { "StringEquals": {"S3:ResourceAccount": TRUSTED_AWS_ACCOUNT_NUMBER} } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -837,7 +837,7 @@ class Test_policy_condition_parser: condition_statement = { "StringEquals": {"S3:ResourceAccount": NON_TRUSTED_AWS_ACCOUNT_NUMBER} } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -845,7 +845,7 @@ class Test_policy_condition_parser: condition_statement = { "StringEquals": {"AWS:PrincipalAccount": [TRUSTED_AWS_ACCOUNT_NUMBER]} } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -858,7 +858,7 @@ class Test_policy_condition_parser: ] } } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -866,7 +866,7 @@ class Test_policy_condition_parser: condition_statement = { "StringEquals": {"AWS:PrincipalAccount": TRUSTED_AWS_ACCOUNT_NUMBER} } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -874,7 +874,7 @@ class Test_policy_condition_parser: condition_statement = { "StringEquals": {"AWS:PrincipalAccount": NON_TRUSTED_AWS_ACCOUNT_NUMBER} } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -882,7 +882,7 @@ class Test_policy_condition_parser: condition_statement = { "StringLike": {"AWS:PrincipalAccount": [TRUSTED_AWS_ACCOUNT_NUMBER]} } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -895,7 +895,7 @@ class Test_policy_condition_parser: ] } } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -903,7 +903,7 @@ class Test_policy_condition_parser: condition_statement = { "StringLike": {"AWS:PrincipalAccount": TRUSTED_AWS_ACCOUNT_NUMBER} } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -911,7 +911,7 @@ class Test_policy_condition_parser: condition_statement = { "StringLike": {"AWS:PrincipalAccount": NON_TRUSTED_AWS_ACCOUNT_NUMBER} } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -924,7 +924,7 @@ class Test_policy_condition_parser: } } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -938,7 +938,7 @@ class Test_policy_condition_parser: } } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -949,7 +949,7 @@ class Test_policy_condition_parser: } } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -960,7 +960,7 @@ class Test_policy_condition_parser: } } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -973,7 +973,7 @@ class Test_policy_condition_parser: } } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -987,7 +987,7 @@ class Test_policy_condition_parser: } } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -998,7 +998,7 @@ class Test_policy_condition_parser: } } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -1009,7 +1009,7 @@ class Test_policy_condition_parser: } } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -1022,7 +1022,7 @@ class Test_policy_condition_parser: } } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -1036,7 +1036,7 @@ class Test_policy_condition_parser: } } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -1047,7 +1047,7 @@ class Test_policy_condition_parser: } } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -1058,7 +1058,7 @@ class Test_policy_condition_parser: } } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -1071,7 +1071,7 @@ class Test_policy_condition_parser: } } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -1085,7 +1085,7 @@ class Test_policy_condition_parser: } } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -1096,7 +1096,7 @@ class Test_policy_condition_parser: } } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -1107,7 +1107,7 @@ class Test_policy_condition_parser: } } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -1120,7 +1120,7 @@ class Test_policy_condition_parser: } } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -1134,7 +1134,7 @@ class Test_policy_condition_parser: } } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -1145,7 +1145,7 @@ class Test_policy_condition_parser: } } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -1156,7 +1156,7 @@ class Test_policy_condition_parser: } } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -1169,7 +1169,7 @@ class Test_policy_condition_parser: } } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -1183,7 +1183,7 @@ class Test_policy_condition_parser: } } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -1194,7 +1194,7 @@ class Test_policy_condition_parser: } } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -1205,7 +1205,7 @@ class Test_policy_condition_parser: } } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -1213,7 +1213,7 @@ class Test_policy_condition_parser: condition_statement = { "StringEquals": {"AWS:ResourceAccount": [TRUSTED_AWS_ACCOUNT_NUMBER]} } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -1226,7 +1226,7 @@ class Test_policy_condition_parser: ] } } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -1234,7 +1234,7 @@ class Test_policy_condition_parser: condition_statement = { "StringEquals": {"AWS:ResourceAccount": TRUSTED_AWS_ACCOUNT_NUMBER} } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -1242,7 +1242,7 @@ class Test_policy_condition_parser: condition_statement = { "StringEquals": {"AWS:ResourceAccount": NON_TRUSTED_AWS_ACCOUNT_NUMBER} } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -1250,7 +1250,7 @@ class Test_policy_condition_parser: condition_statement = { "StringLike": {"AWS:ResourceAccount": [TRUSTED_AWS_ACCOUNT_NUMBER]} } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -1263,7 +1263,7 @@ class Test_policy_condition_parser: ] } } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -1271,7 +1271,7 @@ class Test_policy_condition_parser: condition_statement = { "StringLike": {"AWS:ResourceAccount": TRUSTED_AWS_ACCOUNT_NUMBER} } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -1279,7 +1279,7 @@ class Test_policy_condition_parser: condition_statement = { "StringLike": {"AWS:ResourceAccount": NON_TRUSTED_AWS_ACCOUNT_NUMBER} } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -1298,7 +1298,7 @@ class Test_policy_condition_parser: ] }, } - assert not is_account_only_allowed_in_condition( + assert not is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -1315,7 +1315,7 @@ class Test_policy_condition_parser: ] }, } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -1333,7 +1333,7 @@ class Test_policy_condition_parser: ] }, } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) @@ -1351,6 +1351,18 @@ class Test_policy_condition_parser: ] }, } - assert is_account_only_allowed_in_condition( + assert is_condition_block_restrictive( condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER ) + + def test_condition_parser_allowing_cross_account_with_invalid_block(self): + condition_statement = { + "StringLike": { + "s3:prefix": [ + "home/", + ] + }, + } + assert not is_condition_block_restrictive( + condition_statement, TRUSTED_AWS_ACCOUNT_NUMBER, True + ) diff --git a/tests/providers/aws/services/sqs/sqs_queues_not_publicly_accessible/sqs_queues_not_publicly_accessible_test.py b/tests/providers/aws/services/sqs/sqs_queues_not_publicly_accessible/sqs_queues_not_publicly_accessible_test.py index 35eb5614..ea2a45d4 100644 --- a/tests/providers/aws/services/sqs/sqs_queues_not_publicly_accessible/sqs_queues_not_publicly_accessible_test.py +++ b/tests/providers/aws/services/sqs/sqs_queues_not_publicly_accessible/sqs_queues_not_publicly_accessible_test.py @@ -92,6 +92,21 @@ test_public_policy_with_condition_diff_account = { ], } +test_public_policy_with_invalid_condition_block = { + "Version": "2012-10-17", + "Id": "Queue1_Policy_UUID", + "Statement": [ + { + "Sid": "Queue1_AnonymousAccess_ReceiveMessage", + "Effect": "Allow", + "Principal": "*", + "Action": "sqs:ReceiveMessage", + "Resource": test_queue_arn, + "Condition": {"DateGreaterThan": {"aws:CurrentTime": "2009-01-31T12:00Z"}}, + } + ], +} + class Test_sqs_queues_not_publicly_accessible: def test_no_queues(self): @@ -240,7 +255,7 @@ class Test_sqs_queues_not_publicly_accessible: assert result[0].resource_tags == [] assert result[0].region == AWS_REGION_EU_WEST_1 - def test_queues_public_with_condition_invalid_other_account(self): + def test_queues_public_with_condition_valid_with_other_account(self): sqs_client = mock.MagicMock sqs_client.queues = [] sqs_client.audited_account = AWS_ACCOUNT_NUMBER @@ -261,6 +276,40 @@ class Test_sqs_queues_not_publicly_accessible: sqs_queues_not_publicly_accessible, ) + check = sqs_queues_not_publicly_accessible() + result = check.execute() + assert len(result) == 1 + assert result[0].status == "PASS" + assert ( + result[0].status_extended + == f"SQS queue {test_queue_url} is not public because its policy only allows access from the same account." + ) + assert result[0].resource_id == test_queue_url + assert result[0].resource_arn == test_queue_arn + assert result[0].resource_tags == [] + assert result[0].region == AWS_REGION_EU_WEST_1 + + def test_queues_public_with_condition_with_invalid_block(self): + sqs_client = mock.MagicMock + sqs_client.queues = [] + sqs_client.audited_account = AWS_ACCOUNT_NUMBER + sqs_client.queues.append( + Queue( + id=test_queue_url, + name=test_queue_name, + region=AWS_REGION_EU_WEST_1, + policy=test_public_policy_with_invalid_condition_block, + arn=test_queue_arn, + ) + ) + with mock.patch( + "prowler.providers.aws.services.sqs.sqs_service.SQS", + sqs_client, + ): + from prowler.providers.aws.services.sqs.sqs_queues_not_publicly_accessible.sqs_queues_not_publicly_accessible import ( + sqs_queues_not_publicly_accessible, + ) + check = sqs_queues_not_publicly_accessible() result = check.execute() assert len(result) == 1