Notes added on March 6th
The update was published on [What's New with AWS?], but the news is currently unavailable. In addition, the matched details that were provided when requests matched rules that use regex-related statements in the WAF logs are also unavailable.
Table of Contents
- 1. Introduction
- 2. Where details are located
- 3. When blocked by SQL injection attack rule statement
- 4. When blocked by Regex match rule statement
- 5. When blocked by AWS Managed Rules
- 6. When blocked by String match rule statement
- 7. When detected with action Count
- 8. When blocked by WafCharm rules
- 9. Conclusion
1. Introduction
AWS WAF released an update on February 27th, 2024 to include the details of requests when they match rules that use Regex match rule statement or Regex pattern set match rule statement in WAF logs.
AWS WAF now supports ruleMatchDetails for Regex rules
In this blog post, we will take a look at the details included in the WAF logs.
2. Where details are located
When requests match the rules that use regex-related statements, it seems like the matched data is provided under [terminatingRuleMatchDetails] or [nonTerminatingMatchingRules] in WAF logs.
There are some differences between statements used in rules, but when we reviewed the WAF logs, the common items were as below.
- conditionType: Types of conditions. [REGEX] is used for the Regex match rule statement. SQL injection attack or Cross-site scripting attack rule statements have specific types based on the statement such as [SQL_INJECTION].
- location: Where in the request component the value matched. If the request matched at query string, it would say [QUERY_STRING]; for body data it would say [BODY], and so on.
- matchedData: The actual data that matched the rule.
- matchedFieldName: When requests match components like JSON body or header, the field name is provided.
Details of the fields provided in WAF logs are explained in the Log fields page in AWS official document, but it seems like the description for rule match details hasn't been updated at the time of the release.
This is only populated for SQL injection and cross-site scripting (XSS) match rule statements. The matching rule might require a match for more than one inspection criteria, so these match details are provided as an array of match criteria.
In the following sections, we will take a look at the results from the test using several statements.
*WAF logs provided in this blog post will only show snippets of related information.
3. When blocked by SQL injection attack rule statement
As stated above, detailed information about the matched requests have been available under fields like [terminatingRuleMatchDetails] for SQL injection attack and Cross-site scripting attack rule statements.
No updates are provided with this release for the rule statements above, but we've checked how the data is presented in the WAF logs.
In the snippet below, we can see that strings in the body data matched with the [SQL_INJECTION] statement. The body data sent in the request was one line, but the [matchedData] field in the WAF log divides strings in an array.
"terminatingRuleMatchDetails": [ { "conditionType": "SQL_INJECTION", "location": "BODY", "matchedData": [ "select", "a", "from", "b" ], "matchedFieldName": "", "sensitivityLevel": "LOW" } ],
4. When blocked by Regex match rule statement
As a test, we created a rule that matches when strings [matched * data] are included in body data and sent a request that contains strings [this body contains matched data] in the body.
Because the rule is created with a regex match rule statement, the request was detected with [REGEX] and in the body.
We can also see that [matchedData] contains data that only matches with the rule. In other words, even if the data we sent is [this body contains matched data], the part that doesn't match the rule [this body contains] is not included in the field.
In addition, data in [matchedData] is provided in one line for the regex match rule statement and is not divided into an array per string. This is different from how SQL injection attack rule statement or cross-site scripting attack rule statements behaves.
"terminatingRuleMatchDetails": [ { "conditionType": "REGEX", "location": "BODY", "matchedData": [ "matched data" ], "matchedFieldName": "" } ],
We also looked at the length of data that can be written in the [matchedData] field and found that it can contain quite lengthy data.
"terminatingRuleMatchDetails": [ { "conditionType": "REGEX", "location": "BODY", "matchedData": [ "matched --------------random string for demo------------ data" ], "matchedFieldName": "" } ],
From the test, we could see that up to 1,000 bytes could be written in the field. This information is also provided in the AWS official document.
The logs can report up to 1 K of the matching string for each rule, and truncates the string at 1 K.
If there are a lot of characters between the beginning of the data (e.g.: matched) and the end of the data (e.g.: data) and exceeds the 1000-byte limit, the string [data] at the end will not be present in the WAF log. Those who accept two-byte characters, such as Japanese, would have fewer characters available in the field because the length is counted based on bytes instead of characters.
You may want to keep in mind that the [matchedData] may not be able to provide the complete information if the accepted data is large in size.
5. When blocked by AWS Managed Rules
Matched data is also available for AWS managed rules.
We tested using a core rule set (CRS) managed rule group, and the data were provided just like other rule statements.
"terminatingRuleMatchDetails": [ { "conditionType": "REGEX", "location": "BODY", "matchedData": [ "http://1.1.1.1" ], "matchedFieldName": "" } ],
As stated in the AWS official document, cross-site scripting rules in CRS rule group uses the cross-site scripting attack rule statement, so the data available in [matchedData] is similar to that of SQL injection attack rule statement.
"terminatingRuleMatchDetails": [ { "conditionType": "XSS", "location": "BODY", "matchedData": [ "<", "script" ], "matchedFieldName": "" } ],
6. When blocked by String match rule statement
This update only targets regex-related rule statements as per the release. We tested how WAF logs would look by using the string match rule statement and found that the [terminatingRuleMatchDetails] field would be empty.
"terminatingRuleMatchDetails": [],
A string match rule statement is a convenient option to use when matching with simple strings, but if you want the matched data to be provided in the WAF logs, make sure to use the regex-related rule statements.
7. When detected with action Count
If requests match rules with action Count, the details are provided in the [ruleMatchDetails] under [nonTerminatingMatchingRules].
If the rule action of the example rule we've used above is set to Count, the information provided in the WAF log would be as below.
"nonTerminatingMatchingRules": [ { "ruleId": "regex-statement", "action": "COUNT", "ruleMatchDetails": [ { "conditionType": "REGEX", "location": "BODY", "matchedData": [ "matched data" ], "matchedFieldName": "" } ] } ],
If a rule with action Block is present after the rule to Count and matched both, the information would be available in both [terminatingRuleMatchDetails] and [nonTerminatingMatchingRules].
In the example below, we've added a rule to block requests when a header contains string [test].
"terminatingRuleMatchDetails": [ { "conditionType": "REGEX", "location": "ANY_HEADER", "matchedData": [ "test" ], "matchedFieldName": "test" } ], (SNIP) "nonTerminatingMatchingRules": [ { "ruleId": "regex-statement", "action": "COUNT", "ruleMatchDetails": [ { "conditionType": "REGEX", "location": "BODY", "matchedData": [ "matched data" ], "matchedFieldName": "" } ] } ],
8. When blocked by WafCharm rules
WafCharm rules are constructed using rule statements provided by AWS WAF. Therefore, if requests matched WafCharm rules with regex-related rule statements, the information would be available in the [terminatingRuleMatchDetails] field as shown below.
"terminatingRuleMatchDetails": [ { "conditionType": "REGEX", "location": "BODY", "matchedData": [ "../../" ], "matchedFieldName": "" } ],
As we've seen above, rules that don't use regex-related rule statements would not provide detailed information on the matched data. However, you could look at the [terminatingRuleMatchDetails] field as a reference to see if information is available for requests that match WafCharm rules.
*Due to security reasons, we do not disclose the details of WafCharm rules.
9. Conclusion
Previously, WAF logs didn't contain body data or detailed information about matched data for most of the rules. If you wanted to figure out what matched the rules in body data, you were required to obtain body data separately, which made it difficult to investigate.
Although the update is limited to regex-related rule statements, you will now be able to refer to WAF logs to determine the matched data.
You may not be able to obtain the complete information depending on the size of the matched data, but this update makes the investigation easier in case of false positives.