Azure Policy, Application Gateway WAF and OWASP rulesets

Recently, I was tasked with developing Azure Policy standards for a client. The client wanted to use a standard set of Azure Policy definitions to manage compliance.

A near-universal security standard for web apps — either IaaS- or PaaS-based — is prohibiting them from connecting directly to the internet via an Azure public IP address. Instead, the best practice is to put web apps behind an Azure Application Gateway (App Gateway) proxy.

Microsoft helpfully provides hundreds of built-in Azure Policy definitions. But one of the specific policies I needed is not built-in. It’s one you have to code yourself. More on that in a moment.

Before we get to that example, it’s worth pointing out that for many DevOps types, Azure Policy is a new world. It has its own namespaces, which closely mirror Azure Resource Manager (ARM) types. But — and it’s a big but — Azure Policy definitions use aliases to select type properties. So, while an Azure Policy type — Microsoft.Network, for example — might be familiar, the Azure Policy alias used to inspect that type’s properties probably isn’t.

So, your first task is finding the aliases you might wish to use in a policy definition. Using Microsoft’s documentation, that’s easier said than done. You can browse the GitHub repo containing all the policies, try finding them in the Azure Portal or searching Google (which, hopefully brought you here). It’s beating a dead horse — that nag being Microsoft’s poor documentation — to say that can be a very hard mountain to climb. The doc is just too scattered and poorly organized to help you in any substantive way if you need to code your own policy definition.

Fortunately, Julian Hayward of Microsoft has produced AzAdvertizer — a website that makes searching for built-in policy definitions and, crucially, aliases a snap. AzAdvertizer is indispensable for cloud architects searching for built-in policies and, when you need to code one yourself, discovering which aliases you need to specify. It’s something that should be in Azure itself. Be that as it may, Julian has done us all a great service with AzAdvertizer. I was thunderstruck when I finally found it.

With that said, let’s get back to the scenario my client wanted to implement for web apps:

  • Implement a policy in audit mode that ensures that App Gateway WAF V2 is deployed, and
  • Implement a policy in audit mode that makes sure none of the OWASP managed rules are disabled.

The first one is easy. Using AzAdvertizer, we find a built-in policy that enforces that requirement precisely. Here’s a screenshot showing how easy it is to find in AzAdvertizer. Note that all you need to do to implement it in the Azure Portal is cut and paste the ID guid into Azure Policy search. (Also checkout the insanely cool compliance column in AzAdvertizer that shows which common compliance regimes a built-in policy supports.)

Built-in policy to audit Azure App Gateway WAF (click to enlarge)

But what about that second requirement — the one that requires that all OWASP rules remain enabled? A deep search of AzAdvertizer reveals we have to write that one.

It turns out that Azure Policy considers these “managed rules” and we need an alias for that property to specify in our Azure Policy definition. Once again, AzAdvertizer comes to the rescue. This screen shot shows the correct alias to check to make sure that no OWASP rules have been disabled:

Azure Policy aliases for OWASP managed rules (click to enlarge)

With this information, we can easily create an Azure Policy definition, like this one:

{
    "parameters": {
        "effect": {
            "type": "String",
            "metadata": {
                "displayName": "Effect",
                "description": "Enable or disable the execution of the policy"
            },
            "allowedValues": [
                "Audit",
                "Deny",
                "Disabled"
            ],
            "defaultValue": "Audit"
        }
    },
    "policyRule": {
        "if": {
            "allOf": [
                {
                    "field": "type",
                    "equals": "Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies"
                },
                {
                    "count": {
                        "field": "Microsoft.Network/applicationGatewayWebApplicationFirewallPolicies/managedRules.managedRuleSets[*].ruleGroupOverrides[*]"
                    },
                    "notEquals": 0
                }
            ]
        },
        "then": {
            "effect": "[parameters('effect')]"
        }
    }
}

This policy is quite simple: if the count of any overrides for managed rules is not zero, the policy flags the assigned resources in scope as non-compliant.

Here we can see those two policies scoped to a resource group containing an App Gateway and a web app before I disabled an OWASP rule in the WAF:

Compliant state: App Gateway WAF and all OWASP rules enabled (click to enlarge)

But if we disable even one of the OWASP managed rules in the WAF, as shown below, and start a compliance scan (Start-AzPolicyComplianceScan is convenient for doing this), as we see in the second screenshot, Azure Policy has marked the assigned resource as non-compliant.

Disabling an OWASP managed rule in Azure App Gateway WAF (click to enlarge)
Non-compliant resource due to custom policy checking disabled OWASP managed rule (click to enlarge)

I hope this helps you plumb the details of developing your own Azure Policy definitions. It’s not hard — and made much easier by AzAdvertizer.


Posted

in

, ,

by

Tags:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *