Written in collaboration with @camilamartins
This post will detail how to use Custom Rules on Azure WAF, including some examples of common use cases fulfilled by this rule type. Custom Rules provide a versatile way to build controls that fulfill security requirements and protect applications from attacks that are unique to your applications.
Azure WAF currently offers 3 rule types, which are processed in the following order:
This post focuses on Custom Rules, but it is important to understand how the managed rulesets work. For more information on these, look for future blog posts here or consult the Azure WAF documentation.
Custom Rules can be viewed and built using the Azure Portal by navigating to Web Application Firewall Policies (WAF), selecting your policy, and clicking on the Custom Rules blade. Creating a custom rule is as simple as clicking Add Custom Rule and entering a few required fields. However, there are some important concepts to understand before you create your own rules.
The most important thing to mention about Custom Rules is that they are terminating. This means that if the logic of the rule is matched, all other rules stop processing, including the lower priority (higher number) Custom Rules, and both OWASP and Bot managed rulesets. This is the case regardless of the action of the rule; even if traffic is allowed, no further rules are processed. This can have positive or negative implications.
The Allow action should be used sparingly in Custom Rules, because since the rule terminates, it means that all other inspection provided by WAF will be skipped. Understanding this, you can use Allow rules when the intent is to skip the other checks, such as in tuning situations. If certain requests tend to trigger false positives, you can use a Custom Rule to allow the traffic at a more granular level than it would be possible by using exclusions or disabling rules.
In most scenarios, it is best to use Custom Rules with the Deny action, as a terminating Deny rule is entirely expected and without unanticipated consequences. For instance, if you wanted to use a WAF Custom Rule to create an IP Address allow list, it is better to Deny traffic that is not from the IP addresses in the list rather than Allow traffic from those IPs. Using the Deny action avoids causing traffic allowed by this rule to bypass the OWASP and Bot rulesets.
Another concept to make use of in constructing effective Custom Rules is compound conditions. Rules can be created with a single condition, or you can add multiple conditions that must be satisfied to constitute a match. When adding multiple conditions, they are added as an AND statement, so all conditions must be met for the Action to take place. If you need to construct a rule with OR logic, it is best to create multiple rules with the same Action.
We have created 2 ARM templates, which will create both WAF Policy types, one for WAF on Application Gateway and one for WAF on Front Door. These policies are intended to give you a starting point for creating your own Custom Rules. To deploy, simply click the Deploy to Azure buttons from the repository, select a Resource Group, and create your policies.
These example policies must be modified to fit your requirements before associating with any Front Door or Application Gateway resources, and the following sections will provide guidance on how to do so.
Some customers have the requirement to block certain sources of traffic based on IP address or country of origin. In these scenarios, block lists can be used, which you must create and keep up to date. The examples included in the templates are GeoBlockList and IPBlockList. The behavior of these basic rules can be modified to add conditions if necessary. For example, you may want to block a certain part of a site from a geographic region, as pictured:
Notice that there is a second condition in the "And if" box, which defines a specific request URI. This additional condition creates an AND expression, meaning that both the first condition about geolocation and the second condition about the request URI must be matched in order for the Deny action to trigger.
These block lists can be added manually via the Portal or managed programmatically using ARM, API, or CLI. One example of adding to a block list automatically using Azure Sentinel Playbooks can be found in a previous post.
IP address or geographic restrictions can be accomplished effectively using allow lists. This method is preferable if you only do business in certain countries, or if you have an internal website you would like to be available only to trusted IP addresses, such as corporate IP blocks.
The following example shows the IPAllowList rule found in the template:
Notice that the allow list uses the "Does not contain" operator. This allows our logic to use the Deny action to block only the traffic that does not originate from the trusted range. This means that the trusted IP addresses or ranges will continue to be inspected by the other applicable WAF rules. Using this approach, we can avoid creating a rule using the "Does contain" operation along with the Allow action, which would result in a rule termination scenario that would exempt the trusted traffic from further WAF inspection.
HTTP method enforcement can be done in a dynamic way using WAF Custom Rules. Consider the scenario where you have an API that should be available publicly for customers to GET and POST, but you want to reserve PUT and DELETE actions for traffic originating from trusted locations as an extra layer of security beyond authentication. The following modification of the MethodAllowList rule can be used to accomplish this.
Some of the OWASP managed rules will detect well known malicious user agents, but if you find the need to block a specific set, a Custom Rule is a way to accomplish this. Of course, user agent is not a difficult element for an attacker to change, but this type of rule can help deflect unsophisticated attackers. The logic of the UserAgentBlock rule is represented in the template pictured below.
WAF on Azure Front Door has the added capability of Custom Rules with a Rate Limit type, as distinct from Match type rules. Rate Limit rules will keep track of the number of requests from a particular IP address and block requests made after a threshold is reached.
These rules can be part of an effective layer 7 DDoS protection strategy. Azure DDoS Protection, both at the platform level (free) and using the Standard tier (paid) will protect against high volume attacks, but there are application attacks that do not necessarily rely on high volume. Some of these attacks can be mitigated by using source rate limiting in Custom Rules. The idea is that a legitimate user of a site will make a predictable number of requests to the site over a given time period, but an attacker trying to disrupt the site’s availability would likely make more requests. A threshold can be set to limit the volume of traffic to a particular path from a source, as pictured below.
In the above rate limiting rule, 100 requests from the same IP address would be allowed within any 1 minute time period, but after the threshold is met, additional requests from that IP would be dropped for 1 minute. After the rate limiting period expires, traffic is allowed and the counter to 100 starts again.
A common architectural design is to use Azure Front Door to provide global load balancing and content distribution in front of Application Gateways hosted in 2 or more regions. NSGs can be used on the Application Gateway subnet to only allow traffic from the Front Door service, but the remaining security concern here is that Front Door is a shared service. You probably want to allow traffic only from your Front Door service specifically to prevent an attacker from setting up a “rogue” Front Door instance without WAF in order to circumvent inspection.
Fortunately, Front Door adds a header (X-Azure-FDID) to all traffic it processes, which identifies it as your instance of Front Door. Pictured below is a WAF Custom Rule, AllowFrontDoor in the template, that will only allow traffic that contains this specific header value. This guarantees that traffic sourcing from unapproved Front Door instances will not connect to your service.
The preceding example use cases are not very complex in nature, yet they provide considerable results to improve the security of your applications. We hope these samples help you understand how flexible Custom Rules can be, and that you can use this as a starting point to build more advanced rule logic in your environment. There are many possibilities to add complexity and effectiveness to these examples, including using Regex to look for patterns in the request body. If you come up with any particularly useful rules, please feel free to share in the comments here or add a sample to our GitHub repository.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.