You suspect that the Web Application Firewall (WAF) may be obstructing the functionality of your application. This article provides guidance on diagnosing the issue and adjusting/removing WAF rules as necessary.
- Open
WEB ACLs
tab under the WAF dashboard as shown in figure.
- Make sure you choose the correct region. In this example my WAF is deployed in Ohio(us-east-2). And then click your WAF rule, here in this example the name is managed_rules.
- In this dashboard, you can access comprehensive metrics related to your WAF. Take a moment to review the graphics and metrics to become acquainted with them. Make sure that Blocked button is selected only. However, the information we require is located at the bottom of the page, so please scroll down accordingly.
4.At the bottom, we can see at the Attack Types graph that our WAF detected 3 different attack types as SQL Injection, NoUserAgent and BadBots. We see those 3 because previously I tried to do an SQL injection to my application and also I made HTTPS requests without proper headers. In Requests terminated by managed rule groups you can see which rule groups are blocking your requests. In my case they are AWSManagedRulesSQLiRuleSet (for SQL injection) and AWSManagedRulesCommonRuleSet (for missing and bad agent header). Now that we have gathered some information, our focus needs to shift to the individual rules rather than the rule groups. Let's direct our attention to the graphic located at the bottom left Top 10 managed rule labels.
- If we take a closer look at this graph, we can see exactly when each rule kicks in and stops your access. Just match up the times when you tried to access with the points on the graph. The pink line on the graph shows which rule is stopping you. Below the graph, you'll see a list of rules that were triggered, each with its own color. In my case, it looks like the rule that's causing the trouble is aws:core-rule-set:NoUserAgent_Header. So what does it mean?
- The rule label is aws:core-rule-set:NoUserAgent_Header. After the last column, we see the name of the rule we want to exclude, which is NoUserAgent_Header. I actually sent a request with an empty user agent header, triggering this rule. Now, let's proceed and see how to exclude the rule programmatically.
- The rule NoUserAgent_Header belongs to the core-rule-set, and we need to refer to the corresponding AWS documentation to verify the actual name of NoUserAgent_Header because it is case-sensitive. As shown in the image below, we find the corresponding LABEL and Role Name. So in our case, the rule name I need to use in the exclude list is NoUserAgent_HEADER, not NoUserAgent_Header, because it is case-sensitive. Please take a look at the table below to find corresponding AWS page for your label name that you see in CloudWatch.
Label from CloudWatch | Corresponding AWS Page |
---|---|
core-rule-set | AWSManagedRulesCommonRuleSet |
sql-database | AWSManagedRulesSQLiRuleSet |
windows-os | AWSManagedRulesWindowsRuleSet |
known-bad-inputs | AWSManagedRulesKnownBadInputsRuleSet |
amazon-ip-list | AWSManagedRulesAmazonIpReputationList |
- Now we can go to our root module and define our variables as shown below. We wanted to exclude NoUserAgent_HEADER and I place it under the rules_to_exclude_common list because this rule is part of the AWSManagedRulesCommonRuleSet. As you can see I also exclude as I wish other rules. Here I also excluded SQLi_QUERYARGUMENTS which is a rule blocks SQL injections and also I excluded UserAgent_BadBots_HEADER which inspects for common User-Agent header values that indicate that the request is a bad bot. You can see the code snippet at the bottom of the page.
But why did we place NoUserAgent_HEADER under the rules_to_exclude_commonblock? In the table below, you can identify the corresponding Terraform variable to utilize in your code by comparing it with the Label from the CloudWatch column.
| Label from CloudWatch | Corresponding TF Variable |
|-----------------------|--------------------------------|
| core-rule-set | rules_to_exclude_common |
| sql-database | rules_to_exclude_sql |
| windows-os | rules_to_exclude_windows |
| known-bad-inputs | rules_to_exclude_bad |
| amazon-ip-list | rules_to_exclude_reputation |
Now we can provision our infrastructure with that code (or whichever IaC Tool you use):
$ terraform apply
- Now we can check whether our changes have been applied with going back to the dashboard from STEP 3. In that screen you need to click to Rules.
- Here I will click common. Because I wanted to exclude NoUserAgent_HEADER , and I know that I declared it in exclusion list under the rules_to_exclude_common block and this rule is part of AWSManagedRulesCommonRuleSet.
- Below, you can observe that NoUserAgent_HEADER is explicitly allowed now. Additionally, UserAgent_BadBots_HEADER is allowed, as both have been excluded. Remember that SQLi_QUERYARGUMENTS rule has also been excluded, which you can confirm under the sql section rather than common.
- So finally, you can see that again I send a request with an empty user agent header, but this time I receive successful response rather than
403 Forbidden
.