diff --git a/prowler/CHANGELOG.md b/prowler/CHANGELOG.md index 168efa0652..d97fd7e09e 100644 --- a/prowler/CHANGELOG.md +++ b/prowler/CHANGELOG.md @@ -52,6 +52,7 @@ All notable changes to the **Prowler SDK** are documented in this file. ## [v5.7.6] (Prowler UNRELEASED) ### Fixed +- `organizations_scp_check_deny_regions` check to pass when SCP policies have no statements [(#8091)](https://github.com/prowler-cloud/prowler/pull/8091) - Fix logic in VPC and ELBv2 checks [(#8077)](https://github.com/prowler-cloud/prowler/pull/8077) --- diff --git a/prowler/providers/aws/services/organizations/organizations_scp_check_deny_regions/organizations_scp_check_deny_regions.py b/prowler/providers/aws/services/organizations/organizations_scp_check_deny_regions/organizations_scp_check_deny_regions.py index 8de3f30cdd..cced82a762 100644 --- a/prowler/providers/aws/services/organizations/organizations_scp_check_deny_regions/organizations_scp_check_deny_regions.py +++ b/prowler/providers/aws/services/organizations/organizations_scp_check_deny_regions/organizations_scp_check_deny_regions.py @@ -34,9 +34,9 @@ class organizations_scp_check_deny_regions(Check): "SERVICE_CONTROL_POLICY", [] ): # Statements are not always list - statements = policy.content.get("Statement") - if type(policy.content["Statement"]) is not list: - statements = [policy.content.get("Statement")] + statements = policy.content.get("Statement", []) + if type(statements) is not list: + statements = [statements] for statement in statements: # Deny if Condition = {"StringNotEquals": {"aws:RequestedRegion": [region1, region2]}} diff --git a/tests/providers/aws/services/organizations/organizations_scp_check_deny_regions/organizations_scp_check_deny_regions_test.py b/tests/providers/aws/services/organizations/organizations_scp_check_deny_regions/organizations_scp_check_deny_regions_test.py index c575e4abfd..d6d9941960 100644 --- a/tests/providers/aws/services/organizations/organizations_scp_check_deny_regions/organizations_scp_check_deny_regions_test.py +++ b/tests/providers/aws/services/organizations/organizations_scp_check_deny_regions/organizations_scp_check_deny_regions_test.py @@ -17,6 +17,10 @@ def scp_restrict_regions_with_deny(): return '{"Version":"2012-10-17","Statement":{"Effect":"Deny","NotAction":"s3:*","Resource":"*","Condition":{"StringNotEquals":{"aws:RequestedRegion":["eu-central-1","eu-west-1"]}}}}' +def scp_restrict_regions_without_statement(): + return '{"Version":"2012-10-17"}' + + class Test_organizations_scp_check_deny_regions: @mock_aws def test_no_organization(self): @@ -277,3 +281,74 @@ class Test_organizations_scp_check_deny_regions: result = check.execute() assert len(result) == 0 + + @mock_aws + def test_organizations_scp_check_deny_regions_without_statement(self): + aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1]) + + # Create Organization + conn = client("organizations", region_name=AWS_REGION_EU_WEST_1) + response = conn.describe_organization() + # Delete the default FullAWSAccess policy created by Moto + policies = conn.list_policies(Filter="SERVICE_CONTROL_POLICY")["Policies"] + for policy in policies: + if policy["Name"] == "FullAWSAccess": + policy_id = policy["Id"] + # Detach from all roots + roots = conn.list_roots()["Roots"] + for root in roots: + conn.detach_policy(PolicyId=policy_id, TargetId=root["Id"]) + # Detach from all OUs + ous = conn.list_organizational_units_for_parent( + ParentId=roots[0]["Id"] + )["OrganizationalUnits"] + for ou in ous: + conn.detach_policy(PolicyId=policy_id, TargetId=ou["Id"]) + # Detach from all accounts + accounts = conn.list_accounts()["Accounts"] + for account in accounts: + conn.detach_policy(PolicyId=policy_id, TargetId=account["Id"]) + # Now delete + conn.delete_policy(PolicyId=policy_id) + break + # Create Policy + response_policy = conn.create_policy( + Content=scp_restrict_regions_without_statement(), + Description="Test", + Name="Test", + Type="SERVICE_CONTROL_POLICY", + ) + org_id = response["Organization"]["Id"] + policy_id = response_policy["Policy"]["PolicySummary"]["Id"] + + # Set config variable + aws_provider._audit_config = {"organizations_enabled_regions": ["us-east-1"]} + + with mock.patch( + "prowler.providers.common.provider.Provider.get_global_provider", + return_value=aws_provider, + ): + with mock.patch( + "prowler.providers.aws.services.organizations.organizations_scp_check_deny_regions.organizations_scp_check_deny_regions.organizations_client", + new=Organizations(aws_provider), + ): + # Test Check + from prowler.providers.aws.services.organizations.organizations_scp_check_deny_regions.organizations_scp_check_deny_regions import ( + organizations_scp_check_deny_regions, + ) + + check = organizations_scp_check_deny_regions() + result = check.execute() + + assert len(result) == 1 + assert result[0].status == "FAIL" + assert result[0].resource_id == response["Organization"]["Id"] + assert ( + "arn:aws:organizations::123456789012:organization/o-" + in result[0].resource_arn + ) + assert ( + result[0].status_extended + == f"AWS Organization {org_id} has SCP policies but don't restrict AWS Regions." + ) + assert result[0].region == AWS_REGION_EU_WEST_1