Be Very Careful with Allow Rules in Azure WAF's
I learned something the other day when working on an Azure Front Door Web Application Firewall (WAF) that was surprising and I hadn’t considered before. This can result in you not applying the rules you thought you were applying to your inbound traffic. This applies to both Front Door and App Gateway WAF’s
The Azure WAF has two types of rules, managed rules and custom rules. Managed rules are created and managed by Microsoft and are designed to protect against common threats, including the OWASP top 10. Managed rules cover things like cross-site scripting, Remote Command execution and SQL injection. Custom rules are created by the user and allow you define custom rules that cover lots of scenarios.
It’s very common that you want to create some custom rules that are applied, on top of the managed rules, so that both sets of rules are applied. A common example of this is to create an IP allow list to control where traffic to your site can come from. If a user passes the IP allow rule, you still want to apply the managed rules set to protect against these threats, even from people coming from an allowed set of IP’s.
The Problem
If you are creating an IP-allow rule on your WAF, the obvious way to do this is to create a list of IP’s and allow traffic if the requestor is on the list. The problem with taking this approach is this statement in the WAF docs:
When a request matches a custom rule, the WAF engine stops processing the request. Managed rules won’t be processed for this request and neither will other custom rules with a lower priority.
This means that if a user passes the IP allow rule, the WAF stops processing any further rules. Neither the managed rules set nor any additional custom rules with a lower priority will be processed. This does stop people who do not have the correct IP from accessing your service, but nothing else is applied.
If you’re like me, you probably assumed that the IP allow rule would apply first, and if you passed this rule, then you would process all of the other rules, but that isn’t the case. Given this, you should generally avoid using allow rules unless you absolutely have to or if you do want the processing to stop.
Alternative Approach
To avoid this issue, you can rephrase your rule and invert the processing so that it becomes a deny rule. Instead of a rule that says, “If the IP is in this list, allow access,” you can say, “If the IP is NOT in this list, deny access.” By using this approach, you still block people who are not in the allow list from accessing your service; however, it does not stop processing, and your other custom and managed rules are applied.
Generally, you want to try and use a deny rule wherever possible, to preserve the processing of the rest of your rules.