Search code examples
azureazure-waf

Web Application Firewall Policies - Create Or Update


I use this API from microsoft:

https://learn.microsoft.com/en-us/rest/api/application-gateway/web-application-firewall-policies/create-or-update

{
  "location": "westus",
  "properties": {
    "customRules": [
      {
        "name": "BlockSpec",
        "priority": 85,
        "ruleType": "MatchRule",
        "action": "Block",
        "matchConditions": [
          {
            "matchVariables": [
              {
                "variableName": "RemoteAddr"
              }
            ],
            "operator": "IPMatch",
            "matchValues": [
              "100.60.60.62"
            ],
            "transforms": []
          }
        ],
        "skippedManagedRuleSets": [],
        "state": "Enabled"
      }
    ],
    "policySettings": {
      "requestBodyCheck": true,
      "maxRequestBodySizeInKb": 128,
      "fileUploadLimitInMb": 100,
      "state": "Enabled",
      "mode": "Prevention",
      "requestBodyInspectLimitInKB": 128,
      "fileUploadEnforcement": true,
      "requestBodyEnforcement": true
    },
    "managedRules": {
      "managedRuleSets": [
        {
          "ruleSetType": "OWASP",
          "ruleSetVersion": "3.2",
          "ruleGroupOverrides": []
        }
      ],
      "exclusions": []
    }
  }
}

Assume that you have a policy that has 4 custom rule. When running this API, previous 4 custom rules bing deleted and new one added.

"customRules": [
      {
        "name": "BlockSpec",
        "priority": 85,
        "ruleType": "MatchRule",
        "action": "Block",
        "matchConditions": [
          {
            "matchVariables": [
              {
                "variableName": "RemoteAddr"
              }
            ],
            "operator": "IPMatch",
            "matchValues": [
              "100.60.60.62"
            ],
            "transforms": []
          }
        ],
        "skippedManagedRuleSets": [],
        "state": "Enabled"
      }
    ]

Before:

enter image description here

After:

enter image description here

this always delete the previous one and never update the custom rule. Is there any way to add custom rule inside existing policy without deleting previous one?


Solution

  • Is there any way to add custom rule inside existing policy without deleting previous one?

    According to this MS-Document,

    The Web Application Firewall Policies - Create Or Update API replaces the entire policy, including the customRules array, with the provided payload.

    To preserve the existing custom rules while adding new ones, you need to retrieve the existing policy, merge the rules, and then update the policy.

    In my environment, I created policy with one custom rule like below.

    Portal: enter image description here

    You can use the below python code that add new custom rules without deleting the existing ones in a Web Application Firewall (WAF) policy.

    Code:

    from azure.identity import DefaultAzureCredential
    from azure.mgmt.network import NetworkManagementClient
    
    
    def main():
        client = NetworkManagementClient(
            credential=DefaultAzureCredential(),
            subscription_id="xxxx",
        )
    
        resource_group_name = "xxxxx"
        policy_name = "Policy1"
    
        
        existing_policy = client.web_application_firewall_policies.get(
            resource_group_name=resource_group_name, policy_name=policy_name
        )
        
        new_custom_rule = {
            "name": "Allowspec",
            "priority": 90,
            "ruleType": "MatchRule",
            "action": "Allow",
            "matchConditions": [
                {
                    "matchVariables": [{"variableName": "RemoteAddr"}],
                    "operator": "IPMatch",
                    "matchValues": ["192.168.1.1"],
                    "transforms": [],
                }
            ],
            "state": "Enabled",
        }
    
        # Append the new rule to the existing custom rules
        existing_custom_rules = existing_policy.custom_rules or []
        existing_custom_rules.append(new_custom_rule)
    
        # Update the policy with the modified custom rules
        parameters = {
            "location": existing_policy.location,
            "properties": {
                "customRules": existing_custom_rules,
                "policySettings": existing_policy.policy_settings,
                "managedRules": existing_policy.managed_rules,
            },
        }
    
        # Update the WAF policy
        response = client.web_application_firewall_policies.create_or_update(
            resource_group_name=resource_group_name,
            policy_name=policy_name,
            parameters=parameters,
        )
    
        print(response)
    
    
    if __name__ == "__main__":
        main()
    

    Output:

    {'additional_properties': {}, 'id': '/subscriptions/xxx/resourceGroups/xxx/providers/Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies/Policy1', 'name': 'Policy1', 'type': 'Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies', 'location': 'westus', 'tags': None, 'etag': 'W/"xx"', 'policy_settings': <azure.mgmt.network.models._models_py3.PolicySettings object at 0x00xx0>, 'custom_rules': [<azure.mgmt.network.models._models_py3.WebApplicationFirewallCustomRule object at 0x0000028E27CA71D0>, <azure.mgmt.network.models._models_py3.WebApplicationFirewallCustomRule object at 0x0000028E27CA7230>], 'application_gateways': None, 'provisioning_state': 'Updating', 'resource_state': None, 'managed_rules': <azure.mgmt.network.models._models_py3.ManagedRulesDefinition object at 0x0000028E27CA7170>, 'http_listeners': None, 'path_based_rules': None, 'application_gateway_for_containers': None}
    

    enter image description here

    Now the above code created new custom rule without deleting the existing one.

    Portal: enter image description here