diff --git a/prowler/providers/aws/services/waf/waf_global_rule_with_conditions/__init__.py b/prowler/providers/aws/services/waf/waf_global_rule_with_conditions/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/prowler/providers/aws/services/waf/waf_global_rule_with_conditions/waf_global_rule_with_conditions.metadata.json b/prowler/providers/aws/services/waf/waf_global_rule_with_conditions/waf_global_rule_with_conditions.metadata.json new file mode 100644 index 0000000000..2bded55e45 --- /dev/null +++ b/prowler/providers/aws/services/waf/waf_global_rule_with_conditions/waf_global_rule_with_conditions.metadata.json @@ -0,0 +1,32 @@ +{ + "Provider": "aws", + "CheckID": "waf_global_rule_with_conditions", + "CheckTitle": "AWS WAF Classic Global Rules Should Have at Least One Condition.", + "CheckType": [ + "Software and Configuration Checks/Industry and Regulatory Standards/NIST 800-53 Controls" + ], + "ServiceName": "waf", + "SubServiceName": "", + "ResourceIdTemplate": "arn:aws:waf:account-id:rule/rule-id", + "Severity": "medium", + "ResourceType": "AwsWafRule", + "Description": "Ensure that every AWS WAF Classic Global Rule contains at least one condition.", + "Risk": "An AWS WAF Classic Global rule without any conditions cannot inspect or filter traffic, potentially allowing malicious requests to pass unchecked.", + "RelatedUrl": "https://docs.aws.amazon.com/config/latest/developerguide/waf-global-rule-not-empty.html", + "Remediation": { + "Code": { + "CLI": "aws waf update-rule --rule-id --change-token --updates '[{\"Action\":\"INSERT\",\"Predicate\":{\"Negated\":false,\"Type\":\"IPMatch\",\"DataId\":\"\"}}]' --region ", + "NativeIaC": "", + "Other": "https://docs.aws.amazon.com/securityhub/latest/userguide/waf-controls.html#waf-6", + "Terraform": "" + }, + "Recommendation": { + "Text": "Ensure that every AWS WAF Classic Global rule has at least one condition to properly inspect and manage web traffic.", + "Url": "https://docs.aws.amazon.com/waf/latest/developerguide/classic-web-acl-rules-editing.html" + } + }, + "Categories": [], + "DependsOn": [], + "RelatedTo": [], + "Notes": "" +} diff --git a/prowler/providers/aws/services/waf/waf_global_rule_with_conditions/waf_global_rule_with_conditions.py b/prowler/providers/aws/services/waf/waf_global_rule_with_conditions/waf_global_rule_with_conditions.py new file mode 100644 index 0000000000..f8a607b439 --- /dev/null +++ b/prowler/providers/aws/services/waf/waf_global_rule_with_conditions/waf_global_rule_with_conditions.py @@ -0,0 +1,27 @@ +from prowler.lib.check.models import Check, Check_Report_AWS +from prowler.providers.aws.services.waf.waf_client import waf_client + + +class waf_global_rule_with_conditions(Check): + def execute(self): + findings = [] + for rule in waf_client.rules.values(): + report = Check_Report_AWS(self.metadata()) + report.region = rule.region + report.resource_id = rule.id + report.resource_arn = rule.arn + report.resource_tags = rule.tags + report.status = "FAIL" + report.status_extended = ( + f"AWS WAF Global Rule {rule.name} does not have any conditions." + ) + + if rule.predicates: + report.status = "PASS" + report.status_extended = ( + f"AWS WAF Global Rule {rule.name} has at least one condition." + ) + + findings.append(report) + + return findings diff --git a/prowler/providers/aws/services/waf/waf_service.py b/prowler/providers/aws/services/waf/waf_service.py index 37e5fa0030..3287970ba2 100644 --- a/prowler/providers/aws/services/waf/waf_service.py +++ b/prowler/providers/aws/services/waf/waf_service.py @@ -1,6 +1,6 @@ -from typing import Optional +from typing import Dict, List, Optional -from pydantic import BaseModel +from pydantic import BaseModel, Field from prowler.lib.logger import logger from prowler.lib.scan_filters.scan_filters import is_resource_filtered @@ -11,46 +11,123 @@ class WAF(AWSService): def __init__(self, provider): # Call AWSService's __init__ super().__init__("waf", provider) + self.rules = {} + self.rule_groups = {} self.web_acls = {} - self.__threading_call__(self._list_web_acls) + self._list_rules() + self.__threading_call__(self._get_rule, self.rules.values()) + self._list_rule_groups() self.__threading_call__( - self._list_resources_for_web_acl, self.web_acls.values() + self._list_activated_rules_in_rule_group, self.rule_groups.values() ) + self._list_web_acls() + self.__threading_call__(self._get_web_acl, self.web_acls.values()) - def _list_web_acls(self, regional_client): - logger.info("WAF - Listing Regional Web ACLs...") + def _list_rules(self): + logger.info("WAF - Listing Global Rules...") try: - for waf in regional_client.list_web_acls()["WebACLs"]: + for rule in self.client.list_rules().get("Rules", []): + arn = f"arn:{self.audited_partition}:waf:{self.region}:{self.audited_account}:rule/{rule['RuleId']}" + self.rules[arn] = Rule( + arn=arn, + id=rule.get("RuleId", ""), + region=self.region, + name=rule.get("Name", ""), + ) + + except Exception as error: + logger.error( + f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + + def _get_rule(self, rule): + logger.info(f"WAF - Getting Global Rule {rule.name}...") + try: + get_rule = self.client.get_rule(RuleId=rule.id) + for predicate in get_rule.get("Rule", {}).get("Predicates", []): + rule.predicates.append( + Predicate( + negated=predicate.get("Negated", False), + type=predicate.get("Type", "IPMatch"), + data_id=predicate.get("DataId", ""), + ) + ) + + except Exception as error: + logger.error( + f"{rule.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + + def _list_rule_groups(self): + logger.info("WAF - Listing Global Rule Groups...") + try: + for rule_group in self.client.list_rule_groups().get("RuleGroups", []): + arn = f"arn:{self.audited_partition}:waf:{self.region}:{self.audited_account}:rulegroup/{rule_group['RuleGroupId']}" + self.rule_groups[arn] = RuleGroup( + arn=arn, + region=self.region, + id=rule_group.get("RuleGroupId", ""), + name=rule_group.get("Name", ""), + ) + + except Exception as error: + logger.error( + f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + + def _list_activated_rules_in_rule_group(self, rule_group): + logger.info( + f"WAF - Listing activated rules in Global Rule Group {rule_group.name}..." + ) + try: + for rule in self.client.list_activated_rules_in_rule_group( + RuleGroupId=rule_group.id + ).get("ActivatedRules", []): + rule_arn = f"arn:{self.audited_partition}:waf:{self.region}:{self.audited_account}:rule/{rule.get('RuleId', '')}" + rule_group.rules.append(self.rules[rule_arn]) + + except Exception as error: + logger.error( + f"{rule_group.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + + def _list_web_acls(self): + logger.info("WAF - Listing Global Web ACLs...") + try: + for waf in self.client.list_web_acls()["WebACLs"]: if not self.audit_resources or ( is_resource_filtered(waf["WebACLId"], self.audit_resources) ): - arn = f"arn:{self.audited_partition}:waf:{regional_client.region}:{self.audited_account}:webacl/{waf['WebACLId']}" + arn = f"arn:{self.audited_partition}:waf:{self.region}:{self.audited_account}:webacl/{waf['WebACLId']}" self.web_acls[arn] = WebAcl( arn=arn, name=waf["Name"], id=waf["WebACLId"], albs=[], - region=regional_client.region, + region=self.region, ) except Exception as error: logger.error( - f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" ) - def _list_resources_for_web_acl(self, regional_client): - logger.info("WAF - Describing resources...") + def _get_web_acl(self, acl): + logger.info(f"WAF - Getting Global Web ACL {acl.name}...") try: - for acl in self.web_acls.values(): - if acl.region == regional_client.region: - for resource in regional_client.list_resources_for_web_acl( - WebACLId=acl.id, ResourceType="APPLICATION_LOAD_BALANCER" - )["ResourceArns"]: - acl.albs.append(resource) + get_web_acl = self.client.get_web_acl(WebACLId=acl.id) + for rule in get_web_acl.get("WebACL", {}).get("Rules", []): + rule_id = rule.get("RuleId", "") + if rule.get("Type", "") == "GROUP": + rule_group_arn = f"arn:{self.audited_partition}:waf:{self.region}:{self.audited_account}:rulegroup/{rule_id}" + acl.rule_groups.append(self.rule_groups[rule_group_arn]) + else: + rule_arn = f"arn:{self.audited_partition}:waf:{self.region}:{self.audited_account}:rule/{rule_id}" + acl.rules.append(self.rules[rule_arn]) except Exception as error: logger.error( - f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + f"{acl.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" ) @@ -99,8 +176,10 @@ def _get_rule(self, rule): data_id=predicate.get("DataId", ""), ) ) - except KeyError: - logger.error(f"Rule {rule.name} not found in {rule.region}.") + except Exception as error: + logger.error( + f"{rule.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) def _list_rule_groups(self, regional_client): logger.info("WAFRegional - Listing Regional Rule Groups...") @@ -159,7 +238,7 @@ def _list_web_acls(self, regional_client): ) def _get_web_acl(self, acl): - logger.info(f"WAFRegional - Getting Web ACL {acl.name}...") + logger.info(f"WAFRegional - Getting Regional Web ACL {acl.name}...") try: get_web_acl = self.regional_clients[acl.region].get_web_acl(WebACLId=acl.id) for rule in get_web_acl.get("WebACL", {}).get("Rules", []): @@ -207,8 +286,8 @@ class Rule(BaseModel): id: str region: str name: str - predicates: list[Predicate] = [] - tags: Optional[list] = [] + predicates: Optional[List[Predicate]] = Field(default_factory=list) + tags: Optional[List[Dict[str, str]]] = Field(default_factory=list) class RuleGroup(BaseModel): @@ -218,8 +297,8 @@ class RuleGroup(BaseModel): id: str region: str name: str - rules: list[Rule] = [] - tags: Optional[list] = [] + rules: List[Rule] = Field(default_factory=list) + tags: Optional[List[Dict[str, str]]] = Field(default_factory=list) class WebAcl(BaseModel): @@ -228,8 +307,8 @@ class WebAcl(BaseModel): arn: str name: str id: str - albs: list[str] + albs: List[str] = Field(default_factory=list) region: str - rules: list[Rule] = [] - rule_groups: list[RuleGroup] = [] - tags: Optional[list] = [] + rules: List[Rule] = Field(default_factory=list) + rule_groups: List[RuleGroup] = Field(default_factory=list) + tags: Optional[List[Dict[str, str]]] = Field(default_factory=list) diff --git a/tests/providers/aws/services/waf/waf_global_rule_with_conditions/waf_global_rule_with_conditions_test.py b/tests/providers/aws/services/waf/waf_global_rule_with_conditions/waf_global_rule_with_conditions_test.py new file mode 100644 index 0000000000..5064532ee7 --- /dev/null +++ b/tests/providers/aws/services/waf/waf_global_rule_with_conditions/waf_global_rule_with_conditions_test.py @@ -0,0 +1,167 @@ +from unittest import mock +from unittest.mock import patch + +import botocore +from moto import mock_aws + +from tests.providers.aws.utils import ( + AWS_ACCOUNT_NUMBER, + AWS_REGION_US_EAST_1, + set_mocked_aws_provider, +) + +RULE_ID = "test-rule-id" + +# Original botocore _make_api_call function +orig = botocore.client.BaseClient._make_api_call + + +# Mocked botocore _make_api_call function +def mock_make_api_call_compliant_rule(self, operation_name, kwarg): + if operation_name == "ListRules": + return { + "Rules": [ + { + "RuleId": RULE_ID, + "Name": RULE_ID, + }, + ] + } + if operation_name == "GetRule": + return { + "Rule": { + "RuleId": RULE_ID, + "Predicates": [ + { + "Negated": False, + "Type": "IPMatch", + "DataId": "IPSetId", + }, + ], + } + } + return orig(self, operation_name, kwarg) + + +def mock_make_api_call_non_compliant_rule(self, operation_name, kwarg): + if operation_name == "ListRules": + return { + "Rules": [ + { + "RuleId": RULE_ID, + "Name": RULE_ID, + }, + ] + } + if operation_name == "GetRule": + return { + "Rule": { + "RuleId": RULE_ID, + "Predicates": [], + } + } + return orig(self, operation_name, kwarg) + + +class Test_waf_global_rule_with_conditions: + @mock_aws + def test_no_rules(self): + from prowler.providers.aws.services.waf.waf_service import WAF + + aws_provider = set_mocked_aws_provider([AWS_REGION_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.waf.waf_global_rule_with_conditions.waf_global_rule_with_conditions.waf_client", + new=WAF(aws_provider), + ): + # Test Check + from prowler.providers.aws.services.waf.waf_global_rule_with_conditions.waf_global_rule_with_conditions import ( + waf_global_rule_with_conditions, + ) + + check = waf_global_rule_with_conditions() + result = check.execute() + + assert len(result) == 0 + + @patch( + "botocore.client.BaseClient._make_api_call", + new=mock_make_api_call_compliant_rule, + ) + @mock_aws + def test_waf_rules_with_condition(self): + from prowler.providers.aws.services.waf.waf_service import WAF + + aws_provider = set_mocked_aws_provider([AWS_REGION_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.waf.waf_global_rule_with_conditions.waf_global_rule_with_conditions.waf_client", + new=WAF(aws_provider), + ): + # Test Check + from prowler.providers.aws.services.waf.waf_global_rule_with_conditions.waf_global_rule_with_conditions import ( + waf_global_rule_with_conditions, + ) + + check = waf_global_rule_with_conditions() + result = check.execute() + + assert len(result) == 1 + assert result[0].status == "PASS" + assert ( + result[0].status_extended + == f"AWS WAF Global Rule {RULE_ID} has at least one condition." + ) + assert result[0].resource_id == RULE_ID + assert ( + result[0].resource_arn + == f"arn:aws:waf:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:rule/{RULE_ID}" + ) + assert result[0].region == AWS_REGION_US_EAST_1 + + @patch( + "botocore.client.BaseClient._make_api_call", + new=mock_make_api_call_non_compliant_rule, + ) + @mock_aws + def test_waf_rules_without_condition(self): + from prowler.providers.aws.services.waf.waf_service import WAF + + aws_provider = set_mocked_aws_provider([AWS_REGION_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.waf.waf_global_rule_with_conditions.waf_global_rule_with_conditions.waf_client", + new=WAF(aws_provider), + ): + # Test Check + from prowler.providers.aws.services.waf.waf_global_rule_with_conditions.waf_global_rule_with_conditions import ( + waf_global_rule_with_conditions, + ) + + check = waf_global_rule_with_conditions() + result = check.execute() + + assert len(result) == 1 + assert result[0].status == "FAIL" + assert ( + result[0].status_extended + == f"AWS WAF Global Rule {RULE_ID} does not have any conditions." + ) + assert result[0].resource_id == RULE_ID + assert ( + result[0].resource_arn + == f"arn:aws:waf:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:rule/{RULE_ID}" + ) + assert result[0].region == AWS_REGION_US_EAST_1 diff --git a/tests/providers/aws/services/waf/waf_service_test.py b/tests/providers/aws/services/waf/waf_service_test.py index d86bfe503a..9d85f8c06d 100644 --- a/tests/providers/aws/services/waf/waf_service_test.py +++ b/tests/providers/aws/services/waf/waf_service_test.py @@ -9,7 +9,11 @@ RuleGroup, WAFRegional, ) -from tests.providers.aws.utils import AWS_REGION_EU_WEST_1, set_mocked_aws_provider +from tests.providers.aws.utils import ( + AWS_ACCOUNT_NUMBER, + AWS_REGION_US_EAST_1, + set_mocked_aws_provider, +) # Mocking WAF Calls make_api_call = botocore.client.BaseClient._make_api_call @@ -90,58 +94,187 @@ def mock_make_api_call(self, operation_name, kwarg): # Mock generate_regional_clients() def mock_generate_regional_clients(provider, service): regional_client = provider._session.current_session.client( - service, region_name=AWS_REGION_EU_WEST_1 + service, region_name=AWS_REGION_US_EAST_1 ) - regional_client.region = AWS_REGION_EU_WEST_1 - return {AWS_REGION_EU_WEST_1: regional_client} + regional_client.region = AWS_REGION_US_EAST_1 + return {AWS_REGION_US_EAST_1: regional_client} # Patch every AWS call using Boto3 and generate_regional_clients to have 1 client @patch("botocore.client.BaseClient._make_api_call", new=mock_make_api_call) -@patch( - "prowler.providers.aws.aws_provider.AwsProvider.generate_regional_clients", - new=mock_generate_regional_clients, -) class Test_WAF_Service: - # Test WAF Service - def test_service(self): + # Test WAF Global Service + def test_service_global(self): # WAF client for this test class - aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1]) + aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) waf = WAF(aws_provider) assert waf.service == "waf" - # Test WAF Client - def test_client(self): + # Test WAF Global Client + def test_client_global(self): # WAF client for this test class - aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1]) + aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) waf = WAF(aws_provider) for regional_client in waf.regional_clients.values(): assert regional_client.__class__.__name__ == "WAF" - # Test WAF Session - def test__get_session__(self): + # Test WAF Global Session + def test__get_session___global(self): # WAF client for this test class - aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1]) + aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) waf = WAF(aws_provider) assert waf.session.__class__.__name__ == "Session" - # Test WAF Describe Web ACLs - def test_list_web_acls(self): + # Test WAF Global List Rules + def test_list_rules(self): + # WAF client for this test class + aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) + waf = WAF(aws_provider) + waf_arn = f"arn:aws:waf:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:webacl/my-web-acl-id" + assert waf.web_acls[waf_arn].name == "my-web-acl" + assert waf.web_acls[waf_arn].region == AWS_REGION_US_EAST_1 + assert waf.web_acls[waf_arn].id == "my-web-acl-id" + assert waf.web_acls[waf_arn].rules + assert waf.web_acls[waf_arn].rule_groups + assert waf.rules + + # Test WAF Global Get Rule + def test_get_rule(self): # WAF client for this test class - aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1]) + aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) waf = WAF(aws_provider) - waf_arn = "arn:aws:waf:eu-west-1:123456789012:webacl/my-web-acl-id" + waf_arn = f"arn:aws:waf:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:webacl/my-web-acl-id" + assert waf.web_acls[waf_arn].name == "my-web-acl" + assert waf.web_acls[waf_arn].region == AWS_REGION_US_EAST_1 + assert waf.web_acls[waf_arn].id == "my-web-acl-id" + assert waf.web_acls[waf_arn].rules + assert waf.web_acls[waf_arn].rule_groups + rule_arn = ( + f"arn:aws:waf:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:rule/my-rule-id" + ) + assert waf.rules == { + rule_arn: Rule( + arn=rule_arn, + id="my-rule-id", + name="my-rule", + region=AWS_REGION_US_EAST_1, + predicates=[ + Predicate(negated=False, type="IPMatch", data_id="my-data-id") + ], + ) + } + + # Test WAF Global List Rule Groups + def test_list_rule_groups(self): + # WAF client for this test class + aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) + waf = WAF(aws_provider) + waf_arn = f"arn:aws:waf:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:webacl/my-web-acl-id" + assert waf.web_acls[waf_arn].name == "my-web-acl" + assert waf.web_acls[waf_arn].region == AWS_REGION_US_EAST_1 + assert waf.web_acls[waf_arn].id == "my-web-acl-id" + assert waf.web_acls[waf_arn].rules + assert waf.web_acls[waf_arn].rule_groups + assert waf.rule_groups + + # Test WAF Global Get Rule Groups + def test_get_rule_groups(self): + # WAF client for this test class + aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) + waf = WAF(aws_provider) + waf_arn = f"arn:aws:waf:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:webacl/my-web-acl-id" + assert waf.web_acls[waf_arn].name == "my-web-acl" + assert waf.web_acls[waf_arn].region == AWS_REGION_US_EAST_1 + assert waf.web_acls[waf_arn].id == "my-web-acl-id" + assert waf.web_acls[waf_arn].rules + assert waf.web_acls[waf_arn].rule_groups + rule_arn = f"arn:aws:waf:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:rulegroup/my-rule-group-id" + assert waf.rule_groups == { + rule_arn: RuleGroup( + arn=f"arn:aws:waf:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:rulegroup/my-rule-group-id", + id="my-rule-group-id", + region=AWS_REGION_US_EAST_1, + name="my-rule-group", + rules=[ + Rule( + arn=f"arn:aws:waf:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:rule/my-rule-id", + id="my-rule-id", + region=AWS_REGION_US_EAST_1, + name="my-rule", + predicates=[ + Predicate( + negated=False, type="IPMatch", data_id="my-data-id" + ) + ], + tags=[], + ) + ], + ) + } + + # Test WAF Global List Web ACLs + def test_list_web_acls_waf_global(self): + # WAF client for this test class + aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) + waf = WAF(aws_provider) + waf_arn = f"arn:aws:waf:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:webacl/my-web-acl-id" assert len(waf.web_acls) == 1 assert waf.web_acls[waf_arn].name == "my-web-acl" - assert waf.web_acls[waf_arn].region == AWS_REGION_EU_WEST_1 + assert waf.web_acls[waf_arn].region == AWS_REGION_US_EAST_1 assert waf.web_acls[waf_arn].id == "my-web-acl-id" + assert waf.web_acls[waf_arn].rules + assert waf.web_acls[waf_arn].rule_groups + + # Test WAF Global Get Web ACL + def test_get_web_acl(self): + # WAF client for this test class + aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) + waf = WAF(aws_provider) + waf_arn = f"arn:aws:waf:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:webacl/my-web-acl-id" + assert waf.web_acls[waf_arn].name == "my-web-acl" + assert waf.web_acls[waf_arn].region == AWS_REGION_US_EAST_1 + assert waf.web_acls[waf_arn].id == "my-web-acl-id" + assert waf.web_acls[waf_arn].rules == [ + Rule( + arn=f"arn:aws:waf:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:rule/my-rule-id", + id="my-rule-id", + region=AWS_REGION_US_EAST_1, + name="my-rule", + predicates=[ + Predicate(negated=False, type="IPMatch", data_id="my-data-id") + ], + tags=[], + ) + ] + assert waf.web_acls[waf_arn].rule_groups == [ + RuleGroup( + arn=f"arn:aws:waf:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:rulegroup/my-rule-group-id", + id="my-rule-group-id", + region=AWS_REGION_US_EAST_1, + name="my-rule-group", + rules=[ + Rule( + arn=f"arn:aws:waf:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:rule/my-rule-id", + id="my-rule-id", + region=AWS_REGION_US_EAST_1, + name="my-rule", + predicates=[ + Predicate( + negated=False, type="IPMatch", data_id="my-data-id" + ) + ], + tags=[], + ) + ], + ) + ] # Test WAFRegional Describe Web ACLs Resources def test_list_resources_for_web_acl(self): # WAF client for this test class - aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1]) + aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) waf = WAFRegional(aws_provider) - waf_arn = "arn:aws:waf-regional:eu-west-1:123456789012:webacl/my-web-acl-id" + waf_arn = f"arn:aws:waf-regional:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:webacl/my-web-acl-id" assert len(waf.web_acls) == 1 assert len(waf.web_acls[waf_arn].albs) == 1 assert "alb-arn" in waf.web_acls[waf_arn].albs @@ -149,14 +282,14 @@ def test_list_resources_for_web_acl(self): # Test WAFRegional Service def test_service_regional(self): # WAF client for this test class - aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1]) + aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) waf = WAFRegional(aws_provider) assert waf.service == "waf-regional" # Test WAFRegional Client def test_client_regional(self): # WAF client for this test class - aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1]) + aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) waf = WAFRegional(aws_provider) for regional_client in waf.regional_clients.values(): assert regional_client.__class__.__name__ == "WAFRegional" @@ -164,41 +297,41 @@ def test_client_regional(self): # Test WAFRegional Session def test__get_session___regional(self): # WAF client for this test class - aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1]) + aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) waf = WAFRegional(aws_provider) assert waf.session.__class__.__name__ == "Session" # Test WAFRegional List Rules - def test_list_rules(self): + def test_list_regional_rules(self): # WAF client for this test class - aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1]) + aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) waf = WAFRegional(aws_provider) - waf_arn = "arn:aws:waf-regional:eu-west-1:123456789012:webacl/my-web-acl-id" + waf_arn = f"arn:aws:waf-regional:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:webacl/my-web-acl-id" assert waf.web_acls[waf_arn].name == "my-web-acl" - assert waf.web_acls[waf_arn].region == AWS_REGION_EU_WEST_1 + assert waf.web_acls[waf_arn].region == AWS_REGION_US_EAST_1 assert waf.web_acls[waf_arn].id == "my-web-acl-id" assert waf.web_acls[waf_arn].rules assert waf.web_acls[waf_arn].rule_groups assert waf.rules # Test WAFRegional Get Rule - def test_get_rule(self): + def test_get_regional_rule(self): # WAF client for this test class - aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1]) + aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) waf = WAFRegional(aws_provider) - waf_arn = "arn:aws:waf-regional:eu-west-1:123456789012:webacl/my-web-acl-id" + waf_arn = f"arn:aws:waf-regional:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:webacl/my-web-acl-id" assert waf.web_acls[waf_arn].name == "my-web-acl" - assert waf.web_acls[waf_arn].region == AWS_REGION_EU_WEST_1 + assert waf.web_acls[waf_arn].region == AWS_REGION_US_EAST_1 assert waf.web_acls[waf_arn].id == "my-web-acl-id" assert waf.web_acls[waf_arn].rules assert waf.web_acls[waf_arn].rule_groups - rule_arn = "arn:aws:waf-regional:eu-west-1:123456789012:rule/my-rule-id" + rule_arn = f"arn:aws:waf-regional:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:rule/my-rule-id" assert waf.rules == { rule_arn: Rule( arn=rule_arn, id="my-rule-id", name="my-rule", - region=AWS_REGION_EU_WEST_1, + region=AWS_REGION_US_EAST_1, predicates=[ Predicate(negated=False, type="IPMatch", data_id="my-data-id") ], @@ -206,43 +339,41 @@ def test_get_rule(self): } # Test WAFRegional List Rule Groups - def test_list_rule_groups(self): + def test_list_regional_rule_groups(self): # WAF client for this test class - aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1]) + aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) waf = WAFRegional(aws_provider) - waf_arn = "arn:aws:waf-regional:eu-west-1:123456789012:webacl/my-web-acl-id" + waf_arn = f"arn:aws:waf-regional:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:webacl/my-web-acl-id" assert waf.web_acls[waf_arn].name == "my-web-acl" - assert waf.web_acls[waf_arn].region == AWS_REGION_EU_WEST_1 + assert waf.web_acls[waf_arn].region == AWS_REGION_US_EAST_1 assert waf.web_acls[waf_arn].id == "my-web-acl-id" assert waf.web_acls[waf_arn].rules assert waf.web_acls[waf_arn].rule_groups assert waf.rule_groups # Test WAFRegional Get Rule Groups - def test_get_rule_groups(self): + def test_get_regional_rule_groups(self): # WAF client for this test class - aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1]) + aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) waf = WAFRegional(aws_provider) - waf_arn = "arn:aws:waf-regional:eu-west-1:123456789012:webacl/my-web-acl-id" + waf_arn = f"arn:aws:waf-regional:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:webacl/my-web-acl-id" assert waf.web_acls[waf_arn].name == "my-web-acl" - assert waf.web_acls[waf_arn].region == AWS_REGION_EU_WEST_1 + assert waf.web_acls[waf_arn].region == AWS_REGION_US_EAST_1 assert waf.web_acls[waf_arn].id == "my-web-acl-id" assert waf.web_acls[waf_arn].rules assert waf.web_acls[waf_arn].rule_groups - rule_arn = ( - "arn:aws:waf-regional:eu-west-1:123456789012:rulegroup/my-rule-group-id" - ) + rule_arn = f"arn:aws:waf-regional:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:rulegroup/my-rule-group-id" assert waf.rule_groups == { rule_arn: RuleGroup( - arn="arn:aws:waf-regional:eu-west-1:123456789012:rulegroup/my-rule-group-id", + arn=f"arn:aws:waf-regional:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:rulegroup/my-rule-group-id", id="my-rule-group-id", - region=AWS_REGION_EU_WEST_1, + region=AWS_REGION_US_EAST_1, name="my-rule-group", rules=[ Rule( - arn="arn:aws:waf-regional:eu-west-1:123456789012:rule/my-rule-id", + arn=f"arn:aws:waf-regional:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:rule/my-rule-id", id="my-rule-id", - region=AWS_REGION_EU_WEST_1, + region=AWS_REGION_US_EAST_1, name="my-rule", predicates=[ Predicate( @@ -256,32 +387,32 @@ def test_get_rule_groups(self): } # Test WAFRegional List Web ACLs - def test_list_web_acls_waf_regional(self): + def test_list__regionalweb_acls_waf(self): # WAF client for this test class - aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1]) + aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) waf = WAFRegional(aws_provider) - waf_arn = "arn:aws:waf-regional:eu-west-1:123456789012:webacl/my-web-acl-id" + waf_arn = f"arn:aws:waf-regional:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:webacl/my-web-acl-id" assert len(waf.web_acls) == 1 assert waf.web_acls[waf_arn].name == "my-web-acl" - assert waf.web_acls[waf_arn].region == AWS_REGION_EU_WEST_1 + assert waf.web_acls[waf_arn].region == AWS_REGION_US_EAST_1 assert waf.web_acls[waf_arn].id == "my-web-acl-id" assert waf.web_acls[waf_arn].rules assert waf.web_acls[waf_arn].rule_groups # Test WAFRegional Get Web ACL - def test_get_web_acl(self): + def test_get_regional_web_acl(self): # WAF client for this test class - aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1]) + aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) waf = WAFRegional(aws_provider) - waf_arn = "arn:aws:waf-regional:eu-west-1:123456789012:webacl/my-web-acl-id" + waf_arn = f"arn:aws:waf-regional:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:webacl/my-web-acl-id" assert waf.web_acls[waf_arn].name == "my-web-acl" - assert waf.web_acls[waf_arn].region == AWS_REGION_EU_WEST_1 + assert waf.web_acls[waf_arn].region == AWS_REGION_US_EAST_1 assert waf.web_acls[waf_arn].id == "my-web-acl-id" assert waf.web_acls[waf_arn].rules == [ Rule( - arn="arn:aws:waf-regional:eu-west-1:123456789012:rule/my-rule-id", + arn=f"arn:aws:waf-regional:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:rule/my-rule-id", id="my-rule-id", - region=AWS_REGION_EU_WEST_1, + region=AWS_REGION_US_EAST_1, name="my-rule", predicates=[ Predicate(negated=False, type="IPMatch", data_id="my-data-id") @@ -291,15 +422,15 @@ def test_get_web_acl(self): ] assert waf.web_acls[waf_arn].rule_groups == [ RuleGroup( - arn="arn:aws:waf-regional:eu-west-1:123456789012:rulegroup/my-rule-group-id", + arn=f"arn:aws:waf-regional:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:rulegroup/my-rule-group-id", id="my-rule-group-id", - region=AWS_REGION_EU_WEST_1, + region=AWS_REGION_US_EAST_1, name="my-rule-group", rules=[ Rule( - arn="arn:aws:waf-regional:eu-west-1:123456789012:rule/my-rule-id", + arn=f"arn:aws:waf-regional:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:rule/my-rule-id", id="my-rule-id", - region=AWS_REGION_EU_WEST_1, + region=AWS_REGION_US_EAST_1, name="my-rule", predicates=[ Predicate(