

**Introducing a new console experience for AWS WAF**

You can now use the updated experience to access AWS WAF functionality anywhere in the console. For more details, see [Working with the console](https://docs.aws.amazon.com/waf/latest/developerguide/working-with-console.html). 

# AWS WAF rules
<a name="waf-rules"></a>

This section explains what an AWS WAF rule is and how it works.

An AWS WAF rule defines how to inspect HTTP(S) web requests and the action to take on a request when it matches the inspection criteria. You define rules only in the context of a rule group or protection pack (web ACL). 

Rules don't exist in AWS WAF on their own. They aren't AWS resources, and they don't have Amazon Resource Names (ARNs). You can access a rule by name in the rule group or protection pack (web ACL) where it's defined. You can manage rules and copy them to other protection packs (web ACLs) by using the JSON view of the rule group or protection pack (web ACL) that contains the rule. You can also manage them through the AWS WAF console rule builder, which is available for protection packs (web ACLs) and rule groups.

**Rule name**  
Each rule requires a name. Avoid names that start with `AWS` and names that are used for rule groups or rules that are managed for you by other services. See [Recognizing rule groups provided by other services](waf-service-owned-rule-groups.md). 

**Note**  
If you change the name of a rule and you want the rule's metric name to reflect the change, you must update the metric name as well. AWS WAF doesn't automatically update the metric name for a rule when you change the rule name. You can change the metric name when you edit the rule in the console, by using the rule JSON editor. You can also change both names through the APIs and in any JSON listing that you use to define your protection pack (web ACL) or rule group.

**Rule statement**  
Each rule also requires a rule statement that defines how the rule inspects web requests. The rule statement might contain other, nested statements at any depth, depending on the rule and statement type. Some rule statements take sets of criteria. For example, you can specify up to 10,000 IP addresses or IP address ranges for an IP set match rule.

You can define rules that inspect for criteria like the following: 
+ Scripts that are likely to be malicious. Attackers embed scripts that can exploit vulnerabilities in web applications. This is known as cross-site scripting (XSS).
+ IP addresses or address ranges that requests originate from.
+ Country or geographical location that requests originate from.
+ Length of a specified part of the request, such as the query string.
+ SQL code that is likely to be malicious. Attackers try to extract data from your database by embedding malicious SQL code in a web request. This is known as SQL injection.
+ Strings that appear in the request, for example, values that appear in the `User-Agent` header or text strings that appear in the query string. You can also use regular expressions (regex) to specify these strings.
+ Labels that prior rules in the protection pack (web ACL) have added to the request.

In addition to statements with web request inspection criteria, like the ones in the preceding list, AWS WAF supports logical statements for `AND`, `OR`, and `NOT` that you use to combine statements in a rule. 

For example, based on recent requests that you've seen from an attacker, you might create a rule with a logical `AND` statement that combines the following nested statements: 
+ The requests come from 192.0.2.44.
+ They contain the value `BadBot` in the `User-Agent` header.
+ They appear to include SQL-like code in the query string.

In this case, the web request needs to match all of the statements to result in a match for the top-level `AND`. 

**Topics**
+ [

# Using rule actions in AWS WAF
](waf-rule-action.md)
+ [

# Using rule statements in AWS WAF
](waf-rule-statements.md)
+ [

# Using match rule statements in AWS WAF
](waf-rule-statements-match.md)
+ [

# Using logical rule statements in AWS WAF
](waf-rule-statements-logical.md)
+ [

# Using rate-based rule statements in AWS WAF
](waf-rule-statement-type-rate-based.md)
+ [

# Using rule group rule statements in AWS WAF
](waf-rule-statements-rule-group.md)

# Using rule actions in AWS WAF
<a name="waf-rule-action"></a>

This section explains how rule actions work.

The rule action tells AWS WAF what to do with a web request when it matches the criteria defined in the rule. You can optionally add custom behavior to each rule action. 

**Note**  
Rule actions can be terminating or non-terminating. A terminating action stops the protection pack (web ACL) evaluation of the request and either lets it continue to your protected application or blocks it. 

Here are the rule action options: 
+ **Allow** – AWS WAF allows the request to be forwarded to the protected AWS resource for processing and response. This is a terminating action. In rules that you define, you can insert custom headers into the request before forwarding it to the protected resource.
+ **Block** – AWS WAF blocks the request. This is a terminating action. By default, your protected AWS resource responds with an HTTP `403 (Forbidden)` status code. In rules that you define, you can customize the response. When AWS WAF blocks a request, the Block action settings determine the response that the protected resource sends back to the client. 
+ **Count** – AWS WAF counts the request but does not determine whether to allow it or block it. This is a non-terminating action. AWS WAF continues processing the remaining rules in the protection pack (web ACL). In rules that you define, you can insert custom headers into the request and you can add labels that other rules can match against.
+ **CAPTCHA and Challenge** – AWS WAF uses CAPTCHA puzzles and silent challenges to verify that the request is not coming from a bot, and AWS WAF uses tokens to track recent successful client responses. 

  CAPTCHA puzzles and silent challenges can only run when browsers are accessing HTTPS endpoints. Browser clients must be running in secure contexts in order to acquire tokens. 
**Note**  
You are charged additional fees when you use the CAPTCHA or Challenge rule action in one of your rules or as a rule action override in a rule group. For more information, see [AWS WAF Pricing](https://aws.amazon.com/waf/pricing/).

  These rule actions can be terminating or non-terminating, depending on the state of the token in the request: 
  + **Non-terminating for valid, unexpired token** – If the token is valid and unexpired according to the configured CAPTCHA or challenge immunity time, AWS WAF handles the request similar to the Count action. AWS WAF continues to inspect the web request based on the remaining rules in the protection pack (web ACL). Similar to the Count configuration, in rules that you define, you can optionally configure these actions with custom headers to insert into the request, and you can add labels that other rules can match against. 
  + **Terminating with blocked request for invalid or expired token** – If the token is invalid or the indicated timestamp is expired, AWS WAF terminates the inspection of the web request and blocks the request, similar to the Block action. AWS WAF then responds to the client with a custom response code. For CAPTCHA, if the request contents indicate that the client browser can handle it, AWS WAF sends a CAPTCHA puzzle in a JavaScript interstitial, which is designed to distinguish human clients from bots. For the Challenge action, AWS WAF sends a JavaScript interstitial with a silent challenge that is designed to distinguish normal browsers from sessions that are being run by bots. 

  For additional information, see [CAPTCHA and Challenge in AWS WAF](waf-captcha-and-challenge.md).

For information about customizing requests and responses, see [Customized web requests and responses in AWS WAF](waf-custom-request-response.md).

For information about adding labels to matching requests, see [Web request labeling in AWS WAF](waf-labels.md).

For information about how protection pack (web ACL) and rule settings interact, see [Using protection packs (web ACLs) with rules and rule groups in AWS WAF](web-acl-processing.md). 

# Using rule statements in AWS WAF
<a name="waf-rule-statements"></a>

This section explains how rule statements work.

Rule statements are the part of a rule that tells AWS WAF how to inspect a web request. When AWS WAF finds the inspection criteria in a web request, we say that the web request matches the statement. Every rule statement specifies what to look for and how, according to the statement type. 

Every rule in AWS WAF has a single top-level rule statement, which can contain other statements. Rule statements can be very simple. For example, you could have a statement that provides a set of originating countries to inspect your web requests for or you could have a rule statement in a protection pack (web ACL) that just references a rule group. Rule statements can also be very complex. For example, you could have a statement that combines many other statements with logical AND, OR, and NOT statements. 

For most rules, you can add custom AWS WAF labeling to matching requests. The rules in the AWS Managed Rules rule groups add labels to matching requests. The labels that a rule adds provide information about the request to rules that are evaluated later in the protection pack (web ACL) and also in AWS WAF logs and metrics. For information about labeling, see [Web request labeling in AWS WAF](waf-labels.md) and [Label match rule statement](waf-rule-statement-type-label-match.md).

**Nesting rule statements**  
AWS WAF supports nesting for many rule statements, but not for all. For example, you can't nest a rule group statement inside of another statement. You need to use nesting for some scenarios, such as scope-down statements and logical statements. The rule statement lists and rule details that follow describe the nesting capabilities and requirements for each category and rule.

The visual editor for rules in the console supports only one level of nesting for rule statements. For example, you can nest many types of statements inside a logical AND or OR rule, but you can't nest another AND or OR rule, because that requires a second level of nesting. To implement multiple levels of nesting, provide the rule definition in JSON, either through the JSON rule editor in the console or through the APIs. 

**Topics**
+ [

# Adjusting rule statement settings in AWS WAF
](waf-rule-statement-fields.md)
+ [

# Using scope-down statements in AWS WAF
](waf-rule-scope-down-statements.md)
+ [

# Referencing reusable entities in AWS WAF
](waf-rule-statement-reusable-entities.md)

# Adjusting rule statement settings in AWS WAF
<a name="waf-rule-statement-fields"></a>

This section describes the settings that you can specify in rule statements that inspect a component of the web request. For information on usage, see the individual rule statements at [Using match rule statements in AWS WAF](waf-rule-statements-match.md). 

A subset of these web request components can also be used in rate-based rules, as custom request aggregation keys. For information, see [Aggregating rate-based rules in AWS WAF](waf-rule-statement-type-rate-based-aggregation-options.md).

For the request component settings, you specify the component type itself, and any additional options, depending on the component type. For example, when you inspect a component type that contains text, you can apply text transformations to it before inspecting it. 

**Note**  
Unless otherwise noted, if a web request doesn't have the request component that's specified in the rule statement, AWS WAF evaluates the request as not matching the rule criteria.

**Contents**
+ [

# Request components in AWS WAF
](waf-rule-statement-fields-list.md)
  + [

## HTTP method
](waf-rule-statement-fields-list.md#waf-rule-statement-request-component-http-method)
  + [

## Single header
](waf-rule-statement-fields-list.md#waf-rule-statement-request-component-single-header)
  + [

## All headers
](waf-rule-statement-fields-list.md#waf-rule-statement-request-component-headers)
  + [

## Header order
](waf-rule-statement-fields-list.md#waf-rule-statement-request-component-header-order)
  + [

## Cookies
](waf-rule-statement-fields-list.md#waf-rule-statement-request-component-cookies)
  + [

## URI fragment
](waf-rule-statement-fields-list.md#waf-rule-statement-request-component-uri-fragment)
  + [

## URI path
](waf-rule-statement-fields-list.md#waf-rule-statement-request-component-uri-path)
  + [

## JA3 fingerprint
](waf-rule-statement-fields-list.md#waf-rule-statement-request-component-ja3-fingerprint)
  + [

## JA4 fingerprint
](waf-rule-statement-fields-list.md#waf-rule-statement-request-component-ja4-fingerprint)
  + [

## Query string
](waf-rule-statement-fields-list.md#waf-rule-statement-request-component-query-string)
  + [

## Single query parameter
](waf-rule-statement-fields-list.md#waf-rule-statement-request-component-single-query-param)
  + [

## All query parameters
](waf-rule-statement-fields-list.md#waf-rule-statement-request-component-all-query-params)
  + [

## Body
](waf-rule-statement-fields-list.md#waf-rule-statement-request-component-body)
  + [

## JSON body
](waf-rule-statement-fields-list.md#waf-rule-statement-request-component-json-body)
+ [

# Using forwarded IP addresses in AWS WAF
](waf-rule-statement-forwarded-ip-address.md)
+ [

# Inspecting HTTP/2 pseudo headers in AWS WAF
](waf-rule-statement-request-components-for-http2-pseudo-headers.md)
+ [

# Using text transformations in AWS WAF
](waf-rule-statement-transformation.md)

# Request components in AWS WAF
<a name="waf-rule-statement-fields-list"></a>

This section describes the components of the web request that you can specify for inspection. You specify the request component for match rule statements that look for patterns inside the web request. These types of statements include string match, regex match, size constraint, and SQL injection attack statements. For information on how to use these request component settings, see the individual rule statements at [Using match rule statements in AWS WAF](waf-rule-statements-match.md)

Unless otherwise noted, if a web request doesn't have the request component that's specified in the rule statement, AWS WAF evaluates the request as not matching the rule criteria.

**Note**  
You specify a single request component for each rule statement that requires it. To inspect more than one component of a request, create a rule statement for each component. 

The AWS WAF console and API documentation provide guidance for the request component settings in the following locations: 
+ **Rule builder** on the console – In the **Statement** settings for a regular rule type, choose the component that you want to inspect in the **Inspect** dialogue under **Request components**.
+ **API statement contents** – `FieldToMatch`

The rest of this section describes the options for the part of the web request to inspect. 

**Topics**
+ [

## HTTP method
](#waf-rule-statement-request-component-http-method)
+ [

## Single header
](#waf-rule-statement-request-component-single-header)
+ [

## All headers
](#waf-rule-statement-request-component-headers)
+ [

## Header order
](#waf-rule-statement-request-component-header-order)
+ [

## Cookies
](#waf-rule-statement-request-component-cookies)
+ [

## URI fragment
](#waf-rule-statement-request-component-uri-fragment)
+ [

## URI path
](#waf-rule-statement-request-component-uri-path)
+ [

## JA3 fingerprint
](#waf-rule-statement-request-component-ja3-fingerprint)
+ [

## JA4 fingerprint
](#waf-rule-statement-request-component-ja4-fingerprint)
+ [

## Query string
](#waf-rule-statement-request-component-query-string)
+ [

## Single query parameter
](#waf-rule-statement-request-component-single-query-param)
+ [

## All query parameters
](#waf-rule-statement-request-component-all-query-params)
+ [

## Body
](#waf-rule-statement-request-component-body)
+ [

## JSON body
](#waf-rule-statement-request-component-json-body)

## HTTP method
<a name="waf-rule-statement-request-component-http-method"></a>

Inspects the HTTP method for the request. The HTTP method indicates the type of operation that the web request is asking your protected resource to perform, such as `POST` or `GET`. 

## Single header
<a name="waf-rule-statement-request-component-single-header"></a>

Inspects a single named header in the request. 

For this option, you specify the header name, for example, `User-Agent` or `Referer`. The string match for the name is not case sensitive and is performed after trimming leading and trailing spaces from both the request header and the rule.

## All headers
<a name="waf-rule-statement-request-component-headers"></a>

Inspects all of the request headers, including cookies. You can apply a filter to inspect a subset of all headers. 

For this option, you provide the following specifications: 
+ **Match patterns** – The filter to use to obtain a subset of headers for inspection. AWS WAF looks for these patterns in the headers keys. 

  The match patterns setting can be one of the following: 
  + **All** – Match all keys. Evaluate the rule inspection criteria for all headers. 
  + **Excluded headers** – Inspect only the headers whose keys don't match any of the strings that you specify here. The string match for a key is not case sensitive. The matching is performed after trimming the leading and trailing spaces from request header and the match rule.
  + **Included headers** – Inspect only the headers that have a key that matches one of the strings that you specify here. The string match for a key is not case sensitive. The matching is performed after trimming the leading and trailing spaces from request header and the match rule.
+ **Match scope** – The parts of the headers that AWS WAF should inspect with the rule inspection criteria. You can specify **Keys**, **Values**, or **All** to inspect both keys and values for a match. 

  **All** does not require a match to be found in the keys and a match to be found in the values. It requires a match to be found in the keys or the values or both. To require a match in the keys and in the values, use a logical `AND` statement to combine two match rules, one that inspects the keys and another that inspects the values. 
+ **Oversize handling** – How AWS WAF should handle requests that have header data that is larger than AWS WAF can inspect. AWS WAF can inspect at most the first 8 KB (8,192 bytes) of the request headers and at most the first 200 headers. The content is available for inspection by AWS WAF up to the first limit reached. You can choose to continue the inspection, or to skip inspection and mark the request as matching or not matching the rule. For more information about handling oversize content, see [Oversize web request components in AWS WAF](waf-oversize-request-components.md).

## Header order
<a name="waf-rule-statement-request-component-header-order"></a>

Inspect a string containing the list of the request's header names, ordered as they appear in the web request that AWS WAF receives for inspection. AWS WAF generates the string and then uses that as the field to match component in its inspection. AWS WAF separates the header names in the string with colons and with no added spaces, for example `host:user-agent:accept:authorization:referer`.

For this option, you provide the following specifications: 
+ **Oversize handling** – How AWS WAF should handle requests that have header data that is more numerous or larger than AWS WAF can inspect. AWS WAF can inspect at most the first 8 KB (8,192 bytes) of the request headers and at most the first 200 headers. The content is available for inspection by AWS WAF up to the first limit reached. You can choose to continue inspecting the headers that are available, or to skip inspection and mark the request as matching or not matching the rule. For more information about handling oversize content, see [Oversize web request components in AWS WAF](waf-oversize-request-components.md).

## Cookies
<a name="waf-rule-statement-request-component-cookies"></a>

Inspects all of the request cookies. You can apply a filter to inspect a subset of all cookies. 

For this option, you provide the following specifications: 
+ **Match patterns** – The filter to use to obtain a subset of cookies for inspection. AWS WAF looks for these patterns in the cookie keys. 

  The match patterns setting can be one of the following: 
  + **All** – Match all keys. Evaluate the rule inspection criteria for all cookies. 
  + **Excluded cookies** – Inspect only the cookies whose keys don't match any of the strings that you specify here. The string match for a key is case sensitive and must be exact. 
  + **Included cookies** – Inspect only the cookies that have a key that matches one of the strings that you specify here. The string match for a key is case sensitive and must be exact. 
+ **Match scope** – The parts of the cookies that AWS WAF should inspect with the rule inspection criteria. You can specify **Keys**, **Values**, or **All** for both keys and values. 

  **All** does not require a match to be found in the keys and a match to be found in the values. It requires a match to be found in the keys or the values or both. To require a match in the keys and in the values, use a logical `AND` statement to combine two match rules, one that inspects the keys and another that inspects the values. 
+ **Oversize handling** – How AWS WAF should handle requests that have cookie data that is larger than AWS WAF can inspect. AWS WAF can inspect at most the first 8 KB (8,192 bytes) of the request cookies and at most the first 200 cookies. The content is available for inspection by AWS WAF up to the first limit reached. You can choose to continue the inspection, or to skip inspection and mark the request as matching or not matching the rule. For more information about handling oversize content, see [Oversize web request components in AWS WAF](waf-oversize-request-components.md).

## URI fragment
<a name="waf-rule-statement-request-component-uri-fragment"></a>

**Note**  
Uri Fragment inspection is available only for CloudFront distributions and Application Load Balancers.

Inspects the part of a URL that follows the "\$1" symbol, providing additional information about the resource, for example, \$1section2. For information, see [Uniform Resource Identifier (URI): Generic Syntax](https://tools.ietf.org/html/rfc3986#section-3). 

If you don't use a text transformation with this option, AWS WAF doesn't normalize the URI fragment and inspects it exactly as it receives it from the client in the request. For information about text transformations, see [Using text transformations in AWS WAF](waf-rule-statement-transformation.md).

**Rule statement requirements**  
You must provide a fallback behavior for this rule statement. The fallback behavior is the match status that you want AWS WAF to assign to the web request if URI is missing the fragment or associated service is not Application Load Balancer or CloudFront. If you choose to match, AWS WAF treats the request as matching the rule statement and applies the rule action to the request. If you choose to not match, AWS WAF treats the request as not matching the rule statement.

## URI path
<a name="waf-rule-statement-request-component-uri-path"></a>

Inspects the part of a URL that identifies a resource, for example, `/images/daily-ad.jpg`. For information, see [Uniform Resource Identifier (URI): Generic Syntax](https://tools.ietf.org/html/rfc3986#section-3). 

If you don't use a text transformation with this option, AWS WAF doesn't normalize the URI and inspects it exactly as it receives it from the client in the request. For information about text transformations, see [Using text transformations in AWS WAF](waf-rule-statement-transformation.md).

## JA3 fingerprint
<a name="waf-rule-statement-request-component-ja3-fingerprint"></a>

Inspects the request's JA3 fingerprint. 

**Note**  
JA3 fingerprint inspection is available only for Amazon CloudFront distributions and Application Load Balancers.

The JA3 fingerprint is a 32-character hash derived from the TLS Client Hello of an incoming request. This fingerprint serves as a unique identifier for the client's TLS configuration. AWS WAF calculates and logs this fingerprint for each request that has enough TLS Client Hello information for the calculation. Almost all web requests include this information.

**How to get the JA3 fingerprint for a client**  
You can obtain the JA3 fingerprint for a client's requests from the protection pack (web ACL) logs. If AWS WAF is able to calculate the fingerprint, it includes it in the logs. For information about the logging fields, see [Log fields for protection pack (web ACL) traffic](logging-fields.md).

**Rule statement requirements**  
You can inspect the JA3 fingerprint only inside a string match statement that's set to exactly match the string that you provide. Provide the JA3 fingerprint string from the logs in your string match statement specification, to match with any future requests that have the same TLS configuration. For information about the string match statement, see [String match rule statement](waf-rule-statement-type-string-match.md).

You must provide a fallback behavior for this rule statement. The fallback behavior is the match status that you want AWS WAF to assign to the web request if AWS WAF is unable to calculate the JA3 fingerprint. If you choose to match, AWS WAF treats the request as matching the rule statement and applies the rule action to the request. If you choose to not match, AWS WAF treats the request as not matching the rule statement.

To use this match option, you must log your protection pack (web ACL) traffic. For information, see [Logging AWS WAF protection pack (web ACL) traffic](logging.md).

## JA4 fingerprint
<a name="waf-rule-statement-request-component-ja4-fingerprint"></a>

Inspects the request's JA4 fingerprint. 

**Note**  
JA4 fingerprint inspection is available only for Amazon CloudFront distributions and Application Load Balancers.

The JA4 fingerprint is a 36-character hash derived from the TLS Client Hello of an incoming request. This fingerprint serves as a unique identifier for the client's TLS configuration. JA4 fingerprinting is an extension of the JA3 fingerprinting that can result in fewer unique fingerprints for some browsers. AWS WAF calculates and logs this fingerprint for each request that has enough TLS Client Hello information for the calculation. Almost all web requests include this information.

**How to get the JA4 fingerprint for a client**  
You can obtain the JA4 fingerprint for a client's requests from the protection pack (web ACL) logs. If AWS WAF is able to calculate the fingerprint, it includes it in the logs. For information about the logging fields, see [Log fields for protection pack (web ACL) traffic](logging-fields.md).

**Rule statement requirements**  
You can inspect the JA4 fingerprint only inside a string match statement that's set to exactly match the string that you provide. Provide the JA4 fingerprint string from the logs in your string match statement specification, to match with any future requests that have the same TLS configuration. For information about the string match statement, see [String match rule statement](waf-rule-statement-type-string-match.md).

You must provide a fallback behavior for this rule statement. The fallback behavior is the match status that you want AWS WAF to assign to the web request if AWS WAF is unable to calculate the JA4 fingerprint. If you choose to match, AWS WAF treats the request as matching the rule statement and applies the rule action to the request. If you choose to not match, AWS WAF treats the request as not matching the rule statement.

To use this match option, you must log your protection pack (web ACL) traffic. For information, see [Logging AWS WAF protection pack (web ACL) traffic](logging.md).

## Query string
<a name="waf-rule-statement-request-component-query-string"></a>

Inspects the part of the URL that appears after a `?` character, if any.

**Note**  
For cross-site scripting match statements, we recommend that you choose **All query parameters** instead of **Query string**. Choosing **All query parameters** adds 10 WCUs to the base cost.

## Single query parameter
<a name="waf-rule-statement-request-component-single-query-param"></a>

Inspects a single query parameter that you have defined as part of the query string. AWS WAF inspects the value of the parameter that you specify. 

For this option, you also specify a **Query argument**. For example, if the URL is `www.xyz.com?UserName=abc&SalesRegion=seattle`, you can specify `UserName` or `SalesRegion` for the query argument. The maximum length for the name of the argument is 30 characters. The name is not case sensitive, so if you specify `UserName`, AWS WAF matches all variations of `UserName`, including `username` and `UsERName`.

If the query string contains more than one instance of the query argument that you've specified, AWS WAF inspects all the values for a match, using OR logic. For example, in the URL `www.xyz.com?SalesRegion=boston&SalesRegion=seattle`, AWS WAF evaluates the name that you've specified against `boston` and `seattle`. If either is a match, the inspection is a match.

## All query parameters
<a name="waf-rule-statement-request-component-all-query-params"></a>

Inspects all query parameters in the request. This is similar to the single query parameter component choice, but AWS WAF inspects the values of all arguments within the query string. For example, if the URL is `www.xyz.com?UserName=abc&SalesRegion=seattle`, AWS WAF triggers a match if either the value of `UserName` or `SalesRegion` match the inspection criteria. 

Choosing this option adds 10 WCUs to the base cost.

## Body
<a name="waf-rule-statement-request-component-body"></a>

Inspects the request body, evaluated as plain text. You can also evaluate the body as JSON using the JSON content type. 

The request body is the part of the request that immediately follows the request headers. It contains any additional data that is needed for the web request, for example, data from a form. 
+ In the console, you select this under the **Request option** choice **Body**, by selecting the **Content type** choice **Plain text**. 
+ In the API, in the rule's `FieldToMatch` specification, you specify `Body` to inspect the request body as plain text.

For Application Load Balancer and AWS AppSync, AWS WAF can inspect the first 8 KB of the body of a request. For CloudFront, API Gateway, Amazon Cognito, App Runner, and Verified Access, by default, AWS WAF can inspect the first 16 KB, and you can increase the limit up to 64 KB in your protection pack (web ACL) configuration. For more information, see [Considerations for managing body inspection in AWS WAF](web-acl-setting-body-inspection-limit.md).

You must specify oversize handling for this component type. Oversize handling defines how AWS WAF handles requests that have body data that is larger than AWS WAF can inspect. You can choose to continue the inspection, or to skip inspection and mark the request as matching or not matching the rule. For more information about handling oversize content, see [Oversize web request components in AWS WAF](waf-oversize-request-components.md). 

You can also evaluate the body as parsed JSON. For information about this, see the section that follows. 

## JSON body
<a name="waf-rule-statement-request-component-json-body"></a>

Inspects the request body, evaluated as JSON. You can also evaluate the body as plain text. 

The request body is the part of the request that immediately follows the request headers. It contains any additional data that is needed for the web request, for example, data from a form. 
+ In the console, you select this under the **Request option** choice **Body**, by selecting the **Content type** choice **JSON**. 
+ In the API, in the rule's `FieldToMatch` specification, you specify `JsonBody`.

For Application Load Balancer and AWS AppSync, AWS WAF can inspect the first 8 KB of the body of a request. For CloudFront, API Gateway, Amazon Cognito, App Runner, and Verified Access, by default, AWS WAF can inspect the first 16 KB, and you can increase the limit up to 64 KB in your protection pack (web ACL) configuration. For more information, see [Considerations for managing body inspection in AWS WAF](web-acl-setting-body-inspection-limit.md).

You must specify oversize handling for this component type. Oversize handling defines how AWS WAF handles requests that have body data that is larger than AWS WAF can inspect. You can choose to continue the inspection, or to skip inspection and mark the request as matching or not matching the rule. For more information about handling oversize content, see [Oversize web request components in AWS WAF](waf-oversize-request-components.md). 

Choosing this option doubles the match statement's base cost WCUs. For example, if the match statement base cost is 5 WCUs without JSON parsing, using JSON parsing doubles the cost to 10 WCUs. 

For this option, you provide additional specifications, as described in the following section.

**How AWS WAF handles JSON body inspection**  
When AWS WAF inspects the web request body as JSON, it performs steps to parse the body and extract the JSON elements for inspection. AWS WAF performs these steps in accordance with your configuration choices. 

The following lists the steps that AWS WAF performs. 

1. **Parse the body contents** – AWS WAF parses the contents of the web request body in order to extract the JSON elements for inspection. AWS WAF does its best to parse the entire contents of the body, but parsing can fail for a variety of error states in the contents. Examples include invalid characters, duplicate keys, truncation, and content whose root node isn't an object or an array. 

   The option **Body parsing fallback behavior** determines what AWS WAF does if it fails to completely parse the JSON body: 
   + **None (default behavior)** - AWS WAF evaluates the content only up to the point where it encountered a parsing error. 
   + **Evaluate as string** - Inspect the body as plain text. AWS WAF applies the text transformations and inspection criteria that you defined for the JSON inspection to the body text string.
   + **Match** - Treat the web request as matching the rule statement. AWS WAF applies the rule action to the request.
   + **No match** - Treat the web request as not matching the rule statement.
**Note**  
This fallback behavior only triggers when AWS WAF encounters an error while parsing the JSON string. 

**Parsing doesn't fully validate the JSON**  
AWS WAF parsing doesn't fully validate the input JSON string, so parsing can succeed even for invalid JSON.

   For example, AWS WAF parses the following invalid JSON without error: 
   + Missing comma: `{"key1":"value1""key2":"value2"}`
   + Missing colon: `{"key1":"value1","key2""value2"}`
   + Extra colons: `{"key1"::"value1","key2""value2"}`

   For cases such as these where the parsing succeeds but the result isn't completely valid JSON, the outcome of the subsequent steps in the evaluation can vary. The extraction might miss some elements, or the rule evaluation might have unexpected results. We recommend that you validate the JSON that you receive in your application and handle invalid JSON as needed. 

1. **Extract the JSON elements** – AWS WAF identifies the subset of JSON elements to inspect according to your settings: 
   + The option **JSON match scope** specifies the types of elements in the JSON that AWS WAF should inspect. 

     You can specify **Keys**, **Values**, or **All** for both keys and values. 

     **All** does not require a match to be found in the keys and a match to be found in the values. It requires a match to be found in the keys or the values or both. To require a match in the keys and in the values, use a logical `AND` statement to combine two match rules, one that inspects the keys and another that inspects the values. 
   + The option **Content to inspect** specifies how to filter the element set to the subset that you want AWS WAF to inspect. 

     You must specify one of the following:
     + **Full JSON content** - Evaluate all elements. 
     + **Only included elements** - Evaluate only elements whose paths match the JSON Pointer criteria that you provide. Don't use this option to indicate *all* paths in the JSON. Instead, use **Full JSON content**. 

       For information about JSON Pointer syntax, see the Internet Engineering Task Force (IETF) documentation [JavaScript Object Notation (JSON) Pointer](https://tools.ietf.org/html/rfc6901). 

       For example, in the console, you can provide the following: 

       ```
       /dogs/0/name
       /dogs/1/name
       ```

       In the API or CLI, you can provide the following: 

       ```
       "IncludedPaths": ["/dogs/0/name", "/dogs/1/name"]
       ```

   For example, say that the **Content to inspect** setting is **Only included elements**, and the included elements setting is `/a/b`. 

   For the following example JSON body: 

   ```
   { 
     "a":{
       "c":"d",
       "b":{
         "e":{
           "f":"g"
         }
       }
     }
   }
   ```

   The element sets that AWS WAF would inspect for each **JSON match scope** setting are listed below. Note that the key `b`, which is part of the included elements path, isn't evaluated.
   + **All**: `e`, `f,` and `g`.
   + **Keys**: `e` and `f`.
   + **Values**: `g`.

1. **Inspect the JSON element set** – AWS WAF applies any text transformations that you've specified to the extracted JSON elements and then matches the resulting element set against the rule statement's match criteria. This is the same transformation and evaluation behavior as for other web request components. If any of the extracted JSON elements match, the web request is a match for the rule. 

# Using forwarded IP addresses in AWS WAF
<a name="waf-rule-statement-forwarded-ip-address"></a>

This section applies to rule statements that use the IP address of a web request. By default, AWS WAF uses the IP address from the web request origin. However, if a web request goes through one or more proxies or load balancers, the web request origin will contain the address of the last proxy, and not the originating address of the client. In this case, the originating client address is usually forwarded in another HTTP header. This header is typically `X-Forwarded-For` (XFF), but it can be a different one. 

**Rule statements that use IP addresses**  
The rule statements that use IP addresses are the following:
+ [IP set match](waf-rule-statement-type-ipset-match.md) - Inspects the IP address for a match with the addresses that are defined in an IP set.
+ [Geographic match](waf-rule-statement-type-geo-match.md) - Uses the IP address to determine country and region of origin and matches the country of origin against a list of countries.
+ [ASN match](waf-rule-statement-type-asn-match.md) - Uses the IP address to determine the Autonomous System Number (ASN) and matches the ASN against a list of ASNs.
+ [Using rate-based rule statements](waf-rule-statement-type-rate-based.md) - Can aggregate requests by their IP addresses to ensure that no individual IP address sends requests at too high a rate. You can use IP address aggregation by itself or in combination with other aggregation keys. 

You can instruct AWS WAF to use a forwarded IP address for any of these rule statements, either from the `X-Forwarded-For` header or from another HTTP header, instead of using the web request's origin. For details on how to provide the specifications, see the guidance for the individual rule statement types.

**Note**  
If a header is missing, AWS WAF evaluates any statement that uses that header as "No match." If you use a NOT statement with a "No match" result, AWS WAF converts the evaluation to "Match." Missing headers don't trigger fallback behavior - only invalid header values do.

**Fallback behavior**  
When you use the forwarded IP address, you indicate the match status for AWS WAF to assign to the web request if the request doesn't have a valid IP address in the specified position: 
+ **MATCH** - Treat the web request as matching the rule statement. AWS WAF applies the rule action to the request.
+ **NO MATCH** - Treat the web request as not matching the rule statement. 

**IP addresses used in AWS WAF Bot Control**  
The Bot Control managed rule group verifies bots using the IP addresses from AWS WAF. If you use Bot Control and you have verified bots that route through a proxy or load balancer, you need to explicitly allow them using a custom rule. For example, you can configure a custom IP set match rule that uses forwarded IP addresses to detect and allow your verified bots. You can use the rule to customize your bot management in a number of ways. For information and examples, see [AWS WAF Bot Control](waf-bot-control.md). 

**General considerations for using forwarded IP addresses**  
Before you use a forwarded IP address, note the following general caveats: 
+ A header can be modified by proxies along the way, and the proxies might handle the header in different ways. 
+ Attackers might alter the contents of the header in an attempt to bypass AWS WAF inspections. 
+ The IP address inside the header can be malformed or invalid.
+ The header that you specify might not be present at all in a request.

**Considerations for using forwarded IP addresses with AWS WAF**  
The following list describes requirements and caveats for using forwarded IP addresses in AWS WAF:
+ For any single rule, you can specify one header for the forwarded IP address. The header specification is case insensitive.
+ For rate-based rule statements, any nested scoping statements do not inherit the forwarded IP configuration. Specify the configuration for each statement that uses a forwarded IP address. 
+ For geo match, ASN match, and rate-based rules, AWS WAF uses the first address in the header. For example, if a header contains `10.1.1.1, 127.0.0.0, 10.10.10.10` AWS WAF uses `10.1.1.1`
+ For IP set match, you indicate whether to match against the first, last, or any address in the header. If you specify any, AWS WAF inspects all addresses in the header for a match, up to 10 addresses. If the header contains more than 10 addresses, AWS WAF inspects the last 10. 
+ Headers that contain multiple addresses must use a comma separator between the addresses. If a request uses a separator other than a comma, AWS WAF considers the IP addresses in the header malformed.
+ If the IP addresses inside the header are malformed or invalid, AWS WAF designates the web request as matching the rule or not matching, according to the fallback behavior that you specify in the forwarded IP configuration.
+ If the header that you specify isn’t present in a request, AWS WAF doesn’t apply the rule to the request at all. This means that AWS WAF doesn't apply the rule action and doesn't apply the fallback behavior.
+ A rule statement that uses a forwarded IP header for the IP address won’t use the IP address that’s reported by the web request origin.

**Best practices for using forwarded IP addresses with AWS WAF**  
When you use forwarded IP addresses, use the following best practices: 
+ Carefully consider all possible states of your request headers before enabling forwarded IP configuration. You might need to use more than one rule to get the behavior you want.
+ To inspect multiple forwarded IP headers or to inspect the web request origin and a forwarded IP header, use one rule for each IP address source. 
+ To block web requests that have an invalid header, set the rule action to block and set the fallback behavior for the forwarded IP configuration to match. 

**Example JSON for forwarded IP addresses**  
The following geo match statement matches only if the `X-Forwarded-For` header contains an IP whose country of origin is `US`: 

```
{
  "Name": "XFFTestGeo",
  "Priority": 0,
  "Action": {
    "Block": {}
  },
  "VisibilityConfig": {
    "SampledRequestsEnabled": true,
    "CloudWatchMetricsEnabled": true,
    "MetricName": "XFFTestGeo"
  },
  "Statement": {
    "GeoMatchStatement": {
      "CountryCodes": [
        "US"
      ],
      "ForwardedIPConfig": {
        "HeaderName": "x-forwarded-for",
        "FallbackBehavior": "MATCH"
      }
    }
  }
}
```

The following rate-based rule aggregates requests based on the first IP in the `X-Forwarded-For` header. The rule counts only requests that match the nested geo match statement, and it only blocks requests that match the geo match statement. The nested geo match statement also uses the `X-Forwarded-For` header to determine whether the IP address indicates a country of origin of `US`. If it does, or if the header is present but malformed, the geo match statement returns a match. 

```
{
  "Name": "XFFTestRateGeo",
  "Priority": 0,
  "Action": {
    "Block": {}
  },
  "VisibilityConfig": {
    "SampledRequestsEnabled": true,
    "CloudWatchMetricsEnabled": true,
    "MetricName": "XFFTestRateGeo"
  },
  "Statement": {
    "RateBasedStatement": {
      "Limit": "100",
      "AggregateKeyType": "FORWARDED_IP",
      "ScopeDownStatement": {
        "GeoMatchStatement": {
          "CountryCodes": [
            "US"
          ],
          "ForwardedIPConfig": {
            "HeaderName": "x-forwarded-for",
            "FallbackBehavior": "MATCH"
          }
        }
      },
      "ForwardedIPConfig": {
        "HeaderName": "x-forwarded-for",
        "FallbackBehavior": "MATCH"
      }
    }
  }
}
```

# Inspecting HTTP/2 pseudo headers in AWS WAF
<a name="waf-rule-statement-request-components-for-http2-pseudo-headers"></a>

This section explains how you can use AWS WAF to inspect HTTP/2 pseudo headers.

Protected AWS resources that support HTTP/2 traffic do not forward HTTP/2 pseudo headers to AWS WAF for inspection, but they provide contents of pseudo headers in web request components that AWS WAF inspects. 

You can use AWS WAF to inspect only the pseudo headers that are listed in the following table. 


**HTTP/2 pseudo header contents mapped to web request components**  

| HTTP/2 pseudo header | Web request component to inspect | Documentation | 
| --- | --- | --- | 
|  `:method`  |  HTTP method   |  [HTTP method](waf-rule-statement-fields-list.md#waf-rule-statement-request-component-http-method)  | 
|  `:authority`  |  `Host` header   |  [Single header](waf-rule-statement-fields-list.md#waf-rule-statement-request-component-single-header)  [All headers](waf-rule-statement-fields-list.md#waf-rule-statement-request-component-headers)  | 
|  `:path` URI path  | URI path  | [URI path](waf-rule-statement-fields-list.md#waf-rule-statement-request-component-uri-path) | 
|  `:path` query  |  Query string  |  [Query string](waf-rule-statement-fields-list.md#waf-rule-statement-request-component-query-string) [Single query parameter](waf-rule-statement-fields-list.md#waf-rule-statement-request-component-single-query-param) [All query parameters](waf-rule-statement-fields-list.md#waf-rule-statement-request-component-all-query-params)  | 

# Using text transformations in AWS WAF
<a name="waf-rule-statement-transformation"></a>

This section explains how to provide transformations for AWS WAF to apply before inspecting the request.

In statements that look for patterns or set constraints, you can provide transformations for AWS WAF to apply before inspecting the request. A transformation reformats a web request to eliminate some of the unusual formatting that attackers use in an effort to bypass AWS WAF. 

When you use this with the JSON body request component selection, AWS WAF applies your transformations after parsing and extracting the elements to inspect from the JSON. For more information, see [JSON body](waf-rule-statement-fields-list.md#waf-rule-statement-request-component-json-body).

If you provide more than one transformation, you also set the order for AWS WAF to apply them. 

**WCUs** – Each text transformation is 10 WCUs.

The AWS WAF console and API documentation also provide guidance for these settings in the following locations: 
+ **Rule builder** on the console – **Text transformation**. This option is available when you use request components. 
+ **API statement contents** – `TextTransformations`Options for text transformations

Each transformation listing shows the console and API specifications followed by the description.

Base64 decode – `BASE64_DECODE`  
AWS WAF decodes a Base64-encoded string.

Base64 decode extension – `BASE64_DECODE_EXT`  
AWS WAF decodes a Base64-encoded string, but uses a forgiving implementation that ignores characters that aren't valid. 

Command line – `CMD_LINE`  
This option mitigates situations where attackers might be injecting an operating system command-line command and are using unusual formatting to disguise some or all of the command.   
Use this option to perform the following transformations:  
+ Delete the following characters: `\ " ' ^`
+ Delete spaces before the following characters: `/ (`
+ Replace the following characters with a space: `, ;`
+ Replace multiple spaces with one space
+ Convert uppercase letters, `A-Z`, to lowercase, `a-z`

Compress whitespace – `COMPRESS_WHITE_SPACE`  
AWS WAF compresses white space by replacing multiple spaces with one space and replacing the following characters with a space character (ASCII 32):  
+ Formfeed (ASCII 12)
+ Tab (ASCII 9)
+ Newline (ASCII 10)
+ Carriage return (ASCII 13)
+ Vertical tab (ASCII 11)
+ Non-breaking space (ASCII 160)

CSS decode – `CSS_DECODE`  
AWS WAF decodes characters that were encoded using CSS 2.x escape rules `syndata.html#characters`. This function uses up to two bytes in the decoding process, so it can help to uncover ASCII characters that were encoded using CSS encoding that wouldn’t typically be encoded. It's also useful in countering evasion, which is a combination of a backslash and non-hexadecimal characters. For example, `ja\vascript` for `javascript`.

Escape sequences decode – `ESCAPE_SEQ_DECODE`  
AWS WAF decodes the following ANSI C escape sequences: `\a`, `\b`, `\f`, `\n`, `\r`, `\t`, `\v`, `\\`, `\?`, `\'`, `\"`, `\xHH` (hexadecimal), `\0OOO` (octal). Encodings that aren't valid remain in the output.

Hex decode – `HEX_DECODE`  
AWS WAF decodes a string of hexadecimal characters into a binary.

HTML entity decode – `HTML_ENTITY_DECODE`  
AWS WAF replaces characters that are represented in hexadecimal format `&#xhhhh;` or decimal format `&#nnnn;` with the corresponding characters.  
AWS WAF replaces the following HTML-encoded characters with unencoded characters. This list uses lowercase HTML encoding, but the handling is case insensitive, for example `&QuOt;` and `&quot;` are treated the same.       
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/waf/latest/developerguide/waf-rule-statement-transformation.html)

JS decode – `JS_DECODE`  
AWS WAF decodes JavaScript escape sequences. If a `\uHHHH` code is in the full-width ASCII code range of `FF01-FF5E`, then the higher byte is used to detect and adjust the lower byte. If not, only the lower byte is used and the higher byte is zeroed, causing a possible loss of information.

Lowercase – `LOWERCASE`  
AWS WAF converts uppercase letters (A-Z) to lowercase (a-z).

MD5 – `MD5`  
AWS WAF calculates an MD5 hash from the data in the input. The computed hash is in a raw binary form.

None – `NONE`  
AWS WAF inspects the web request as received, without any text transformations. 

Normalize path – `NORMALIZE_PATH`  
AWS WAF normalizes the input string by removing multiple slashes, directory self-references, and directory back-references that are not at the beginning of the input.

Normalize path Windows – `NORMALIZE_PATH_WIN`  
AWS WAF converts backslash characters to forward slashes and then processes the resulting string using the `NORMALIZE_PATH` transformation.

Remove nulls – `REMOVE_NULLS`  
AWS WAF removes all `NULL` bytes from the input. 

Replace comments – `REPLACE_COMMENTS`  
AWS WAF replaces each occurrence of a C-style comment (/\$1 ... \$1/) with a single space. It doesn't compress multiple consecutive occurrences. It replaces unterminated comments with a space (ASCII 0x20). It doesn't change a standalone termination of a comment (\$1/).

Replace nulls – `REPLACE_NULLS`  
AWS WAF replaces each `NULL` byte in the input with the space character (ASCII 0x20).

SQL hex decode – `SQL_HEX_DECODE`  
AWS WAF decodes SQL hex data. For example, AWS WAF decodes (`0x414243`) to (`ABC`).

URL decode – `URL_DECODE`  
AWS WAF decodes a URL-encoded value.

URL decode Unicode – `URL_DECODE_UNI`  
Like `URL_DECODE`, but with support for Microsoft-specific `%u` encoding. If the code is in the full-width ASCII code range of `FF01-FF5E`, the higher byte is used to detect and adjust the lower byte. Otherwise, only the lower byte is used and the higher byte is zeroed.

UTF8 to Unicode – `UTF8_TO_UNICODE`  
AWS WAF converts all UTF-8 character sequences to Unicode. This helps normalize input and it minimizes false-positives and false-negatives for non-English languages.

# Using scope-down statements in AWS WAF
<a name="waf-rule-scope-down-statements"></a>

This section explains what a scope-down statement and how it works.

A scope-down statement is a nestable rule statement that you add inside a managed rule group statement or a rate-based statement to narrow the set of requests that the containing rule evaluates. The containing rule only evaluates the requests that first match the scope-down statement. 
+ **Managed rule group statement** – If you add a scope-down statement to a managed rule group statement, AWS WAF evaluates any request that doesn't match the scope-down statement as not matching the rule group. Only those requests that match the scope-down statement are evaluated against the rule group. For managed rule groups with pricing that's based on the number of requests evaluated, scope-down statements can help contain costs. 

  For more information about managed rule group statements, see [Using managed rule group statements in AWS WAF](waf-rule-statement-type-managed-rule-group.md).
+ **Rate-based rule statement** – A rate-based rule statement without a scope-down statement rate limits all requests that the rule evaluates. If you want to only control the rate for a specific category of requests, add a scope-down statement to the rate-based rule. For example, to only track and control the rate of requests from a specific geographical area, you can specify that geographical area in a geographic match statement and add it to your rate-based rule as the scope-down statement. 

  For more information about rate-based rule statements, see [Using rate-based rule statements in AWS WAF](waf-rule-statement-type-rate-based.md).

You can use any nestable rule in a scope-down statement. For the available statements, see [Using match rule statements in AWS WAF](waf-rule-statements-match.md) and [Using logical rule statements in AWS WAF](waf-rule-statements-logical.md). The WCUs for a scope-down statement are the WCUs required for the rule statement that you define in it. There's no additional cost for the use of a scope-down statement.

You can configure a scope-down statement in the same way as you do when you use the statement in a regular rule. For example, you can apply text transformations to a web request component that you're inspecting and you can specify a forwarded IP address to use as the IP address. These configurations apply only to the scope-down statement and are not inherited by the containing managed rule group or rate-based rule statement. 

For example, if you apply text transformations to a query string in your scope-down statement, the scope-down statement inspects the query string after applying the transformations. If the request matches the scope-down statement criteria, AWS WAF then passes the web request to the containing rule in its original state, without the scope-down statement's transformations. The rule that contains the scope-down statement might apply text transformations of its own, but it doesn't inherit any from the scope-down statement. 

You can't use a scope-down statement to specify any request inspection configuration for the containing rule statement. You can't use a scope-down statement as a web request preprocessor for the containing rule statement. The only role of a scope-down statement is to determine which requests are passed to the containing rule statement for inspection. 

# Referencing reusable entities in AWS WAF
<a name="waf-rule-statement-reusable-entities"></a>

This section explains how reusable entities work in AWS WAF.

Some rules use entities that are reusable and that are managed outside of your web ACLs, either by you, AWS, or an AWS Marketplace seller. When the reusable entity is updated, AWS WAF propagates the update to your rule. For example, if you use an AWS Managed Rules rule group in a protection pack (web ACL), when AWS updates the rule group, AWS propagates the change to your web ACL, to update its behavior. If you use an IP set statement in a rule, when you update the set, AWS WAF propagates the change to all rules that reference it, so any protection packs (web ACLs) that use those rules are kept up-to-date with your changes. 

The following are the reusable entities that you can use in a rule statement. 
+ **IP sets** – You create and manage your own IP sets. On the console, you can access these from the navigation pane. For information about managing IP sets, see [IP sets and regex pattern sets in AWS WAF](waf-referenced-set-managing.md). 
+ **Regex match sets** – You create and manage your own regex match sets. On the console, you can access these from the navigation pane. For information about managing regex pattern sets, see [IP sets and regex pattern sets in AWS WAF](waf-referenced-set-managing.md). 
+ **AWS Managed Rules rule groups** – AWS manages these rule groups. On the console, these are available for your use when you add a managed rule group to your protection pack (web ACL). For more information about these, see [AWS Managed Rules rule groups list](aws-managed-rule-groups-list.md).
+ **AWS Marketplace managed rule groups** – AWS Marketplace sellers manage these rule groups and you can subscribe to them to use them. To manage your subscriptions, on the navigation pane of the console, choose **AWS Marketplace**. The AWS Marketplace managed rule groups are listed when you add a managed rule group to your protection pack (web ACL). For rule groups that you haven't yet subscribed to, you can find a link to AWS Marketplace on that page as well. For more information about AWS Marketplace seller managed rule groups, see [AWS Marketplace rule groups](marketplace-rule-groups.md).
+ **Your own rule groups** – You manage your own rule groups, usually when you need some behavior that isn't available through the managed rule groups. On the console, you can access these from the navigation pane. For more information, see [Managing your own rule groups](waf-user-created-rule-groups.md).

**Deleting a referenced set or rule group**  
When you delete a referenced entity, AWS WAF checks to see if it's currently being used in a protection pack (web ACL). If AWS WAF finds that it's in use, it warns you. AWS WAF is almost always able to determine if an entity is being referenced by a protection pack (web ACL). However, in rare cases, it might not be able to do so. If you need to be sure that the entity that you want to delete isn't in use, check for it in your web ACLs before deleting it.

# Using match rule statements in AWS WAF
<a name="waf-rule-statements-match"></a>

This section explains what a match statement is and how it works.

Match statements compare the web request or its origin against criteria that you provide. For many statements of this type, AWS WAF compares a specific component of the request for matching content. 

Match statements are nestable. You can nest any of these statements inside logical rule statements and you can use them in scope-down statements. For information about logical rule statements, see [Using logical rule statements in AWS WAF](waf-rule-statements-logical.md). For information about scope-down statements, see [Using scope-down statements in AWS WAF](waf-rule-scope-down-statements.md).

This table describes the regular match statements that you can add to a rule and provides some guidelines for calculating protection pack (web ACL) capacity units (WCU) usage for each. For information about WCUs, see [Web ACL capacity units (WCUs) in AWS WAF](aws-waf-capacity-units.md). 


| Match Statement | Description | WCUs | 
| --- | --- | --- | 
| [Geographic match](waf-rule-statement-type-geo-match.md) | Inspects the request's country of origin and applies labels for the country and region of origin.  | 1 | 
|  [ASN match](waf-rule-statement-type-asn-match.md)  |  Inspects the request against an ASN associated with IP addresses and address ranges.  |  1  | 
|  [IP set match](waf-rule-statement-type-ipset-match.md)  |  Inspects the request against a set of IP addresses and address ranges.   |  1 for most cases. If you configure the statement to use a header with forwarded IP addresses and specify a position in the header of Any, then increase the WCUs by 4.  | 
|  [Label match rule statement](waf-rule-statement-type-label-match.md)  |  Inspects the request for labels that have been added by other rules in the same protection pack (web ACL).  |  1   | 
| [Regex match rule statement](waf-rule-statement-type-regex-match.md) | Compares a regex pattern against a specified request component.  | 3, as a base cost. If you use the request component **All query parameters**, add 10 WCUs. If you use the request component **JSON body**, double the base cost WCUs. For each **Text transformation** that you apply, add 10 WCUs.  | 
|  [Regex pattern set](waf-rule-statement-type-regex-pattern-set-match.md)  |  Compares regex patterns against a specified request component.   |  25 per pattern set, as a base cost.  If you use the request component **All query parameters**, add 10 WCUs. If you use the request component **JSON body**, double the base cost WCUs. For each **Text transformation** that you apply, add 10 WCUs.  | 
| [Size constraint](waf-rule-statement-type-size-constraint-match.md) | Checks size constraints against a specified request component.  | 1, as a base cost.  If you use the request component **All query parameters**, add 10 WCUs. If you use the request component **JSON body**, double the base cost WCUs. For each **Text transformation** that you apply, add 10 WCUs.  | 
| [SQLi attack](waf-rule-statement-type-sqli-match.md) | Inspects for malicious SQL code in a specified request component.  | 20, as a base cost. If you use the request component **All query parameters**, add 10 WCUs. If you use the request component **JSON body**, double the base cost WCUs. For each **Text transformation** that you apply, add 10 WCUs. | 
| [String match](waf-rule-statement-type-string-match.md) | Compares a string to a specified request component.  |  The base cost depends on the type of string match and is between 1 and 10. If you use the request component **All query parameters**, add 10 WCUs. If you use the request component **JSON body**, double the base cost WCUs. For each **Text transformation** that you apply, add 10 WCUs.  | 
| [XSS scripting attack](waf-rule-statement-type-xss-match.md) | Inspects for cross-site scripting attacks in a specified request component.  | 40, as a base cost. If you use the request component **All query parameters**, add 10 WCUs. If you use the request component **JSON body**, double the base cost WCUs. For each **Text transformation** that you apply, add 10 WCUs. | 

# Geographic match rule statement
<a name="waf-rule-statement-type-geo-match"></a>

This section explains what a geographic match statement is and how it works.

Use geographic or geo match statements to manage web requests based on country and region of origin. A geo match statement add labels to web requests that indicate the country of origin and the region of origin. It adds these labels regardless of whether the statement criteria is a match for the request. A geo match statement also performs matching against the request's country of origin.

## How to use the geo match statement
<a name="waf-rule-statement-geo-how-to-use"></a>

You can use the geo match statement for country or region matching, as follows: 
+ **Country** — You can use a geo match rule by itself to manage requests based solely on their country of origin. The rule statement matches against country codes. You can also follow a geo match rule with a label match rule that matches on the country of origin label. 
**Note**  
To filter traffic from Hong Kong, use the ISO 3166-1 alpha-2 country code `HK` in your geo match statement.
+ **Region** — Use a geo match rule followed by a label match rule to manage requests based on their region of origin. You can't use a geo match rule alone to match against region codes.

For information about using label match rules, see [Label match rule statement](waf-rule-statement-type-label-match.md) and [Web request labeling in AWS WAF](waf-labels.md).

## How the geo match statement works
<a name="waf-rule-statement-geo-how-it-works"></a>

With the geo match statement, AWS WAF manages each web request as follows: 

1. **Determines the request's country and region codes** — AWS WAF determines the country and region of a request based on its IP address. By default, AWS WAF uses the IP address of the web request's origin. You can instruct AWS WAF to use an IP address from an alternate request header, like `X-Forwarded-For`, by enabling forwarded IP configuration in the rule statement settings. 

   AWS WAF determines the location of requests using MaxMind GeoIP databases. MaxMind reports very high accuracy of their data at the country level, although accuracy varies according to factors such as country and type of IP. For more information about MaxMind, see [MaxMind IP Geolocation](https://support.maxmind.com/hc/en-us/sections/4407519834267-IP-Geolocation). If you think any of the GeoIP data is incorrect, you can submit a correction request to Maxmind at [MaxMind Correct GeoIP2 Data](https://support.maxmind.com/hc/en-us/articles/4408252036123-GeoIP-Correction).

   AWS WAF uses the alpha-2 country and region codes from the International Organization for Standardization (ISO) 3166 standard. You can find the codes at the following locations:
   + At the ISO website, you can search the country codes at [ISO Online Browsing Platform (OBP)](https://www.iso.org/obp/ui#home). 
   + On Wikipedia, the country codes are listed at [ISO 3166-2](https://en.wikipedia.org/wiki/ISO_3166-2).

     The region codes for a country are listed at the URL `https://en.wikipedia.org/wiki/ISO_3166-2:<ISO country code>`. For example, the regions for the United States are at [ISO 3166-2:US](https://en.wikipedia.org/wiki/ISO_3166-2:US) and for Ukraine they're at [ISO 3166-2:UA](https://en.wikipedia.org/wiki/ISO_3166-2:UA).

1. **Determines the country label and region label to add to the request** — The labels indicate whether the geo match statement uses the origin IP or a forwarded IP configuration.
   + **Origin IP** 

     The country label is `awswaf:clientip:geo:country:<ISO country code>`. Example for the United States: `awswaf:clientip:geo:country:US`.

     The region label is `awswaf:clientip:geo:region:<ISO country code>-<ISO region code>`. Example for Oregon in the United States: `awswaf:clientip:geo:region:US-OR`.
   + **Forwarded IP** 

     The country label is `awswaf:forwardedip:geo:country:<ISO country code>`. Example for the United States: `awswaf:forwardedip:geo:country:US`.

     The region label is `awswaf:forwardedip:geo:region:<ISO country code>-<ISO region code>`. Example for Oregon in the United States: `awswaf:forwardedip:geo:region:US-OR`.

   If the country or region code isn't available for a request's specified IP address, AWS WAF uses `XX` in the labels, in the place of the value. For example, the following label is for a client IP whose country code isn't available: `awswaf:clientip:geo:country:XX` and the following is for a forwarded IP whose country is the United States, but whose region code isn't available: `awswaf:forwardedip:geo:region:US-XX`. 

1. **Evaluates the request's country code against the rule criteria** 

The geo match statement adds country and region labels to all requests that it inspects, regardless of whether it finds a match. 

**Note**  
AWS WAF adds any labels at the end of a rule's web request evaluation. Because of this, any label matching that you use against the labels from a geo match statement must be defined in a separate rule from the rule that contains the geo match statement. 

If you want to inspect only region values, you can write a geo match rule with Count action and with a single country code match, followed by a label match rule for the region labels. You are required to supply a country code for the geo match rule to evaluate, even for this approach. You can reduce logging and count metrics by specifying a country that's very unlikely to be a source of traffic to your site. 

## CloudFront distributions and the CloudFront geo restriction feature
<a name="cloudfront-distributions-geo-restriction"></a>

For CloudFront distributions, if you use the CloudFront geo restriction feature, be aware that the feature doesn't forward blocked requests to AWS WAF. It does forward allowed requests to AWS WAF. If you want to block requests based on the geography plus other criteria that you can specify in AWS WAF, use the AWS WAF geo match statement and don't use the CloudFront geo restriction feature. 

## Rule statement characteristics
<a name="geo-match-statement-characteristics"></a>

**Nestable** – You can nest this statement type. 

**WCUs ** – 1 WCU.

**Settings** – This statement uses the following settings: 
+ **Country codes** – An array of country codes to compare for a geo match. These must be two-character country codes from the alpha-2 country ISO codes of the ISO 3166 international standard, for example, `["US","CN"]`. 
+ **(Optional) Forwarded IP configuration** – By default, AWS WAF uses the IP address in the web request origin to determine country of origin. Alternatively, you can configure the rule to use a forwarded IP in an HTTP header like `X-Forwarded-For` instead. AWS WAF uses the first IP address in the header. With this configuration, you also specify a fallback behavior to apply to a web request with a malformed IP address in the header. The fallback behavior sets the matching result for the request, to match or no match. For more information, see [Using forwarded IP addresses](waf-rule-statement-forwarded-ip-address.md). 

## Where to find this rule statement
<a name="geo-match-statement-where-to-find"></a>
+ **Rule builder** on the console – For **Request option**, choose **Originates from a country in**.
+ **API** – [GeoMatchStatement](https://docs.aws.amazon.com/waf/latest/APIReference/API_GeoMatchStatement.html)

## Examples
<a name="waf-rule-statement-geo-examples"></a>

You can use the geo match statement to manage requests from specific countries or regions. For example, if you want to block requests from certain countries, but still allow requests from a specific set of IP addresses in those countries, you could create a rule with the action set to Block and the following nested statements, shown in pseudocode:
+ AND statement
  + Geo match statement listing the countries that you want to block
  + NOT statement 
    + IP set statement that specifies the IP addresses that you want to allow through

Or, if you want to block some regions in certain countries, but still allow requests from other regions in those countries, you could first define a geo match rule with the action set to Count. Then, define a label match rule that matches against the added geo match labels and handles the requests as you need. 

The following pseudo code describes an example of this approach:

1. Geo match statement listing the countries with regions that you want to block, but with the action set to Count. This labels every web request regardless of match status, and it also gives you count metrics for the countries of interest. 

1. `AND` statement with Block action
   + Label match statement that specifies the labels for the countries that you want to block
   + `NOT` statement 
     + Label match statement that specifies the labels of the regions in those countries that you want to allow through

The following JSON listing shows an implementation of the two rules described in the prior pseudocode. These rules block all traffic from the United States except for traffic from Oregon and Washington. The geo match statement adds country and region labels to all requests that it inspects. The label match rule runs after the geo match rule, so it can match against the country and region labels that the geo match rule has just added. The geo match statement uses a forwarded IP address, so the label matching also specifies forwarded IP labels. 

```
{
   "Name": "geoMatchForLabels",
   "Priority": 10,
   "Statement": {
     "GeoMatchStatement": {
       "CountryCodes": [
         "US"
       ],
       "ForwardedIPConfig": {
           "HeaderName": "X-Forwarded-For",
           "FallbackBehavior": "MATCH"
       }
     }
   },
   "Action": {
     "Count": {}
   },
   "VisibilityConfig": {
     "SampledRequestsEnabled": true,
     "CloudWatchMetricsEnabled": true,
     "MetricName": "geoMatchForLabels"
   }
},
{
   "Name": "blockUSButNotOROrWA",
   "Priority": 11,
   "Statement": {
     "AndStatement": {
       "Statements": [
         {
           "LabelMatchStatement": {
             "Scope": "LABEL",
             "Key": "awswaf:forwardedip:geo:country:US"
           }
         },
         {
           "NotStatement": {
             "Statement": {
                "OrStatement": {
                  "Statements": [
                    {
                       "LabelMatchStatement": {
                         "Scope": "LABEL",
                         "Key": "awswaf:forwardedip:geo:region:US-OR"
                       }
                    },
                    {
                       "LabelMatchStatement": {
                         "Scope": "LABEL",
                         "Key": "awswaf:forwardedip:geo:region:US-WA"
                       }
                    }
                 ]
               }
             }
           }
         }
       ]
     }
   },
   "Action": {
     "Block": {}
   },
   "VisibilityConfig": {
     "SampledRequestsEnabled": true,
     "CloudWatchMetricsEnabled": true,
     "MetricName": "blockUSButNotOROrWA"
   }
}
```

As another example, you can combine geo matching with rate-based rules to prioritize resources for users in a particular country or region. You create a different rate-based statement for each geo match or label match statement that you use to differentiate your users. Set a higher rate limit for users in the preferred country or region and set a lower rate limit for other users. 

The following JSON listing shows a geo match rule followed by rate-based rules that limit the rate of traffic from the United States. The rules allow traffic from Oregon to come in at a higher rate than traffic from anywhere else in the country. 

```
{
  "Name": "geoMatchForLabels",
  "Priority": 190,
  "Statement": {
    "GeoMatchStatement": {
      "CountryCodes": [
        "US"
      ]
    }
  },
  "Action": {
    "Count": {}
  },
  "VisibilityConfig": {
    "SampledRequestsEnabled": true,
    "CloudWatchMetricsEnabled": true,
    "MetricName": "geoMatchForLabels"
  }
},
{
  "Name": "rateLimitOregon",
  "Priority": 195,
  "Statement": {
    "RateBasedStatement": {
      "Limit": 3000,
      "AggregateKeyType": "IP",
      "ScopeDownStatement": {
        "LabelMatchStatement": {
          "Scope": "LABEL",
          "Key": "awswaf:clientip:geo:region:US-OR"
        }
      }
    }
  },
  "Action": {
    "Block": {}
  },
  "VisibilityConfig": {
    "SampledRequestsEnabled": true,
    "CloudWatchMetricsEnabled": true,
    "MetricName": "rateLimitOregon"
  }
},
{
  "Name": "rateLimitUSNotOR",
  "Priority": 200,
  "Statement": {
    "RateBasedStatement": {
      "Limit": 100,
      "AggregateKeyType": "IP",
      "ScopeDownStatement": {
        "AndStatement": {
          "Statements": [
            {
              "LabelMatchStatement": {
                "Scope": "LABEL",
                "Key": "awswaf:clientip:geo:country:US"
              }
            },
            {
              "NotStatement": {
                "Statement": {
                  "LabelMatchStatement": {
                    "Scope": "LABEL",
                    "Key": "awswaf:clientip:geo:region:US-OR"
                  }
                }
              }
            }
          ]
        }
      }
    }
  },
  "Action": {
    "Block": {}
  },
  "VisibilityConfig": {
    "SampledRequestsEnabled": true,
    "CloudWatchMetricsEnabled": true,
    "MetricName": "rateLimitUSNotOR"
  }
}
```

# IP set match rule statement
<a name="waf-rule-statement-type-ipset-match"></a>

This section explains what an IP set match statement is and how it works.

The IP set match statement inspects the IP address of a web request against a set of IP addresses and address ranges. Use this to allow or block web requests based on the IP addresses that the requests originate from. By default, AWS WAF uses the IP address from the web request origin, but you can configure the rule to use an HTTP header like `X-Forwarded-For` instead. 



AWS WAF supports all IPv4 and IPv6 CIDR ranges except for `/0`. For more information about CIDR notation, see the Wikipedia entry [Classless Inter-Domain Routing](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing). An IP set can hold up to 10,000 IP addresses or IP address ranges to check.

**Note**  
Each IP set match rule references an IP set, which you create and maintain independent of your rules. You can use a single IP set in multiple rules, and when you update the referenced set, AWS WAF automatically updates all rules that reference it.   
For information about creating and managing an IP set, see [Creating and managing an IP set in AWS WAF](waf-ip-set-managing.md).

When you add or update the rules in your rule group or protection pack (web ACL), choose the option **IP set** and select the name of the IP set that you want to use. 

## Rule statement characteristics
<a name="ipset-match-characteristics"></a>

**Nestable** – You can nest this statement type. 

**WCUs** – 1 WCU for most. If you configure the statement to use forwarded IP addresses and specify a position of ANY, increase the WCU usage by 4.

This statement uses the following settings: 
+ **IP set specification** – Choose the IP set that you want to use from the list or create a new one. 
+ **(Optional) Forwarded IP configuration** – An alternate forwarded IP header name to use in place of the request origin. You specify whether to match against the first, last, or any address in the header. You also specify a fallback behavior to apply to a web request with a malformed IP address in the specified header. The fallback behavior sets the matching result for the request, to match or no match. For more information, see [Using forwarded IP addresses](waf-rule-statement-forwarded-ip-address.md). 

## Where to find this rule statement
<a name="ipset-match-where-to-find"></a>

**Where to find this rule statement**
+ **Rule builder** on the console – For **Request option**, choose **Originates from an IP address in**.
+ **Add my own rules and rule groups** page on the console – Choose the **IP set** option.
+ **API** – [IPSetReferenceStatement](https://docs.aws.amazon.com/waf/latest/APIReference/API_IPSetReferenceStatement.html)

# Autonomous System Number (ASN) match rule statement
<a name="waf-rule-statement-type-asn-match"></a>

An ASN match rule statement in AWS WAF allows you to inspect web traffic based on the Autonomous System Number (ASN) associated with the request's IP address. ASNs are unique identifiers assigned to large internet networks managed by organizations such as internet service providers, enterprises, universities, or government agencies. By using ASN match statements, you can allow or block traffic from specific network organizations without having to manage individual IP addresses. This approach offers a more stable and efficient way to control access compared to IP-based rules, as ASNs change less frequently than IP ranges. 

ASN matching is particularly useful for scenarios such as blocking traffic from known problematic networks or allowing access only from trusted partner networks. The ASN match statement provides flexibility in determining the client IP address through optional forwarded IP configuration, making it compatible with various network setups including those using content delivery networks (CDNs) or reverse proxies.

**Note**  
ASN matching supplements, but doesn't replace, standard authentication and authorization controls. We recommend that you implement authentication and authorization mechanisms, such as IAM, to verify the identity of all requests in your applications.

## How the ASN match statement works
<a name="waf-rule-statement-type-asn-match-how-it-works"></a>

AWS WAF determines the ASN of a request based on its IP address. By default, AWS WAF uses the IP address of the web request's origin. You can configure AWS WAF to use an IP address from an alternate request header, like `X-Forwarded-For`, by enabling forwarded IP configuration in the rule statement settings.

The ASN match statement compares the request's ASN against the list of ASNs specified in the rule. If the ASN matches one in the list, the statement evaluates to true, and the associated rule action is applied.

### Handling unmapped ASNs
<a name="waf-rule-statement-type-asn-match-unmapped"></a>

If AWS WAF cannot determine an ASN for a valid IP address, it assigns ASN 0. You can include ASN 0 in your rule to handle these cases explicitly.

### Fallback Behavior for Invalid IP Addresses
<a name="waf-rule-statement-type-asn-match-fallback"></a>

When you configure the ASN match statement to use forwarded IP addresses, you can specify a fallback behavior of *Match* or *No match* for requests with invalid or missing IP addresses in the designated header.

## Rule statement characteristics
<a name="waf-rule-statement-type-asn-match-characteristics"></a>

**Nestable** – You can nest this statement type. 

**WCUs** – 1 WCU

This statement uses the following settings:
+ **ASN list** – An array of ASN numbers to compare for an ASN match. Valid values range from 0 to 4294967295. You can specify up to 100 ASNs for each rule.
+ **(Optional) Forwarded IP configuration** – By default, AWS WAF uses the IP address in the web request origin to determine the ASN. Alternatively, you can configure the rule to use a forwarded IP in an HTTP header like `X-Forwarded-For` instead. You specify whether to use the first, last, or any address in the header. With this configuration, you also specify a fallback behavior to apply to a web request with a malformed IP address in the header. The fallback behavior sets the matching result for the request, to match or no match. For more information, see [Using forwarded IP addresses](https://docs.aws.amazon.com/waf/latest/developerguide/waf-rule-statement-forwarded-ip-address.html).

## Where to find this rule statement
<a name="waf-rule-statement-type-asn-match-where-to-find"></a>
+ **Rule builder** on the console – For **Request option**, choose **Originates from ASN in**.
+ **API** – [AsnMatchStatement](https://docs.aws.amazon.com/waf/latest/APIReference/API_AsnMatchStatement.html)

## Examples
<a name="waf-rule-statement-type-asn-match-examples"></a>

This example blocks requests originating from two specific ASNs derived from an `X-Forwarded-For` header. If the IP address in the header is malformed, the configured fallback behavior is `NO_MATCH`.

```
{
  "Action": {
    "Block": {}
  },
  "Name": "AsnMatchStatementRule",
  "Priority": 1,
  "Statement": {
    "AsnMatchStatement": {
      "AsnList": [64496, 64500]
    },
    "ForwardedIPConfig": {
      "FallbackBehavior": "NO_MATCH",
      "HeaderName": "X-Forwarded-For"
    }
  },
  "VisibilityConfig": {
    "CloudWatchMetricsEnabled": true,
    "MetricName": "AsnMatchRuleMetrics",
    "SampledRequestsEnabled": true
  }
},
"VisibilityConfig": {
  "CloudWatchMetricsEnabled": true,
  "MetricName": "WebAclMetrics",
  "SampledRequestsEnabled": true
}
}
```

# Label match rule statement
<a name="waf-rule-statement-type-label-match"></a>

This section explains what a label match statement is and how it works.

The label match statement inspects the labels that are on the web request against a string specification. The labels that are available to a rule for inspection are those that have already been added to the web request by other rules in the same protection pack (web ACL) evaluation. 

Labels don't persist outside of the protection pack (web ACL) evaluation, but you can access label metrics in CloudWatch and you can see summaries of label information for any protection pack (web ACL) in the AWS WAF console. For more information, see [Label metrics and dimensions](waf-metrics.md#waf-metrics-label) and [Monitoring and tuning your AWS WAF protections](web-acl-testing-activities.md). You can also see labels in the logs. For information, see [Log fields for protection pack (web ACL) traffic](logging-fields.md).

**Note**  
A label match statement can only see labels from rules that are evaluated earlier in the protection pack (web ACL). For information about how AWS WAF evaluates the rules and rule groups in a protection pack (web ACL), see [Setting rule priority](web-acl-processing-order.md).

For more information about adding and matching labels, see [Web request labeling in AWS WAF](waf-labels.md).

## Rule statement characteristics
<a name="label-match-characteristics"></a>

**Nestable** – You can nest this statement type. 

**WCUs** – 1 WCU

This statement uses the following settings: 
+ **Match scope** – Set this to **Label** to match against the label name and, optionally, the preceding namespaces and prefix. Set this to **Namespace** to match against some or all of the namespace specifications and, optionally, the preceding prefix. 
+ **Key** – The string that you want to match against. If you specify a namespace match scope, this should only specify namespaces and optionally the prefix, with an ending colon. If you specify a label match scope, this must include the label name and can optionally include preceding namespaces and prefix. 

For more information about these settings, see [AWS WAF rules that match labels](waf-rule-label-match.md) and [AWS WAF label match examples](waf-rule-label-match-examples.md).

## Where to find this rule statement
<a name="label-match-where-to-find"></a>
+ **Rule builder** on the console – For **Request option**, choose **Has label**.
+ **API** – [LabelMatchStatement](https://docs.aws.amazon.com/waf/latest/APIReference/API_LabelMatchStatement.html)

# Regex match rule statement
<a name="waf-rule-statement-type-regex-match"></a>

This section explains what a regex match statement is and how it works.

A regex match statement instructs AWS WAF to match a request component against a single regular expression (regex). A web request matches the statement if the request component matches the regex that you specify. 

This statement type is a good alternative to the [Regex pattern set match rule statement](waf-rule-statement-type-regex-pattern-set-match.md) for situations where you want to combine your matching criteria using mathematical logic. For example, if you want a request component to match against some regex patterns and to not match against others, you can combine the regex match statements using the [AND rule statement](waf-rule-statement-type-and.md) and the [NOT rule statement](waf-rule-statement-type-not.md). 

AWS WAF supports the pattern syntax used by the PCRE library `libpcre` with some exceptions. The library is documented at [PCRE - Perl Compatible Regular Expressions](http://www.pcre.org/). For information about AWS WAF support, see [Supported regular expression syntax in AWS WAF](waf-regex-pattern-support.md).

## Rule statement characteristics
<a name="regex-match-characteristics"></a>

**Nestable** – You can nest this statement type. 

**WCUs** – 3 WCUs, as a base cost. If you use the request component **All query parameters**, add 10 WCUs. If you use the request component **JSON body**, double the base cost WCUs. For each **Text transformation** that you apply, add 10 WCUs.

This statement type operates on a web request component, and requires the following request component settings: 
+ **Request component** – The part of the web request to inspect, for example, a query string or the body.
**Warning**  
If you inspect the request components **Body**, **JSON body**, **Headers**, or **Cookies**, read about the limitations on how much content AWS WAF can inspect at [Oversize web request components in AWS WAF](waf-oversize-request-components.md). 

  For information about web request components, see [Adjusting rule statement settings in AWS WAF](waf-rule-statement-fields.md).
+ **Optional text transformations** – Transformations that you want AWS WAF to perform on the request component before inspecting it. For example, you could transform to lowercase or normalize white space. If you specify more than one transformation, AWS WAF processes them in the order listed. For information, see [Using text transformations in AWS WAF](waf-rule-statement-transformation.md).

## Where to find this rule statement
<a name="regex-match-where-to-find"></a>
+ **Rule builder** on the console – For **Match type**, choose **Matches regular expression**.
+ **API** – [RegexMatchStatement](https://docs.aws.amazon.com/waf/latest/APIReference/API_RegexMatchStatement.html)

# Regex pattern set match rule statement
<a name="waf-rule-statement-type-regex-pattern-set-match"></a>

This section explains what a regex pattern set match statement is and how it works.

The regex pattern set match inspects the part of the web request that you specify for the regular expression patterns that you've specified inside a regex pattern set.

AWS WAF supports the pattern syntax used by the PCRE library `libpcre` with some exceptions. The library is documented at [PCRE - Perl Compatible Regular Expressions](http://www.pcre.org/). For information about AWS WAF support, see [Supported regular expression syntax in AWS WAF](waf-regex-pattern-support.md).

**Note**  
Each regex pattern set match rule references a regex pattern set, which you create and maintain independent of your rules. You can use a single regex pattern set in multiple rules, and when you update the referenced set, AWS WAF automatically updates all rules that reference it.   
For information about creating and managing a regex pattern set, see [Creating and managing a regex pattern set in AWS WAF](waf-regex-pattern-set-managing.md).

A regex pattern set match statement instructs AWS WAF to search for any of the patterns in the set inside the request component that you choose. A web request will match the pattern set rule statement if the request component matches any of the patterns in the set. 

If you want to combine your regex pattern matches using logic, for example to match against some regular expressions and not match against others, consider using [Regex match rule statement](waf-rule-statement-type-regex-match.md). 

## Rule statement characteristics
<a name="regex-pattern-set-match-characteristics"></a>

**Nestable** – You can nest this statement type. 

**WCUs** – 25 WCUs, as a base cost. If you use the request component **All query parameters**, add 10 WCUs. If you use the request component **JSON body**, double the base cost WCUs. For each **Text transformation** that you apply, add 10 WCUs.

This statement type operates on a web request component, and requires the following request component settings: 
+ **Request component** – The part of the web request to inspect, for example, a query string or the body.
**Warning**  
If you inspect the request components **Body**, **JSON body**, **Headers**, or **Cookies**, read about the limitations on how much content AWS WAF can inspect at [Oversize web request components in AWS WAF](waf-oversize-request-components.md). 

  For information about web request components, see [Adjusting rule statement settings in AWS WAF](waf-rule-statement-fields.md).
+ **Optional text transformations** – Transformations that you want AWS WAF to perform on the request component before inspecting it. For example, you could transform to lowercase or normalize white space. If you specify more than one transformation, AWS WAF processes them in the order listed. For information, see [Using text transformations in AWS WAF](waf-rule-statement-transformation.md).

This statement requires the following settings: 
+ Regex pattern set specification – Choose the regex pattern set that you want to use from the list or create a new one. 

## Where to find this rule statement
<a name="regex-pattern-set-match-where-to-find"></a>
+ **Rule builder** on the console – For **Match type**, choose **String match condition** > **Matches pattern from regular expression set**.
+ **API** – [RegexPatternSetReferenceStatement](https://docs.aws.amazon.com/waf/latest/APIReference/API_RegexPatternSetReferenceStatement.html)

# Size constraint rule statement
<a name="waf-rule-statement-type-size-constraint-match"></a>

This section explains what a size constraint statement is and how it works.

A size constraint statement compares the number of bytes that AWS WAF receives for a web request component to a number that you provide, and matches according to your comparison criteria. 

The comparison criteria is an operator such as greater than (>) or less than (<). For example, you can match on requests that have a query string with a size that's greater than 100 bytes. 

If you inspect the URI path, any `/` in the path counts as one character. For example, the URI path `/logo.jpg` is nine characters long.

**Note**  
This statement only inspects the size of the web request component. It doesn't inspect the contents of the component. 

## Rule statement characteristics
<a name="size-constraint-match-characteristics"></a>

**Nestable** – You can nest this statement type. 

**WCUs** – 1 WCU, as a base cost. If you use the request component **All query parameters**, add 10 WCUs. If you use the request component **JSON body**, double the base cost WCUs. For each **Text transformation** that you apply, add 10 WCUs.

This statement type operates on a web request component, and requires the following request component settings: 
+ **Request component** – The part of the web request to inspect, for example, a query string or the body. For information about web request components, see [Adjusting rule statement settings in AWS WAF](waf-rule-statement-fields.md).

  A size constraint statement inspects only the size of the component after any transformations have been applied. It does not inspect the contents of the component. 
+ **Optional text transformations** – Transformations that you want AWS WAF to perform on the request component before inspecting its size. For example, you could compress white space or decode HTML entities. If you specify more than one transformation, AWS WAF processes them in the order listed. For information, see [Using text transformations in AWS WAF](waf-rule-statement-transformation.md).

Additionally, this statement requires the following settings: 
+ **Size match condition** – This indicates the numerical comparison operator to use to compare the size that you provide with the request component that you've chosen. Choose the operator from the list.
+ **Size** – The size setting, in bytes, to use in the comparison. 

## Where to find this rule statement
<a name="size-constraint-match-where-to-find"></a>
+ **Rule builder** on the console – For **Match type**, under **Size match condition**, choose the condition that you want to use.
+ **API** – [SizeConstraintStatement](https://docs.aws.amazon.com/waf/latest/APIReference/API_SizeConstraintStatement.html)

# SQL injection attack rule statement
<a name="waf-rule-statement-type-sqli-match"></a>

This section explains what a SQL injection rule statement is and how it works.

An SQL injection rule statement inspects for malicious SQL code. Attackers insert malicious SQL code into web requests in order to do things like modify your database or extract data from it.

## Rule statement characteristics
<a name="sqli-match-characteristics"></a>

**Nestable** – You can nest this statement type. 

**WCUs** – The base cost depends on the sensitivity level setting for the rule statement: Low costs 20 and High costs 30. 

If you use the request component **All query parameters**, add 10 WCUs. If you use the request component **JSON body**, double the base cost WCUs. For each **Text transformation** that you apply, add 10 WCUs.

This statement type operates on a web request component, and requires the following request component settings: 
+ **Request component** – The part of the web request to inspect, for example, a query string or the body.
**Warning**  
If you inspect the request components **Body**, **JSON body**, **Headers**, or **Cookies**, read about the limitations on how much content AWS WAF can inspect at [Oversize web request components in AWS WAF](waf-oversize-request-components.md). 

  For information about web request components, see [Adjusting rule statement settings in AWS WAF](waf-rule-statement-fields.md).
+ **Optional text transformations** – Transformations that you want AWS WAF to perform on the request component before inspecting it. For example, you could transform to lowercase or normalize white space. If you specify more than one transformation, AWS WAF processes them in the order listed. For information, see [Using text transformations in AWS WAF](waf-rule-statement-transformation.md).

Additionally, this statement requires the following setting: 
+ **Sensitivity level** – This setting tunes the sensitivity of the SQL injection match criteria. The options are LOW and HIGH. The default setting is LOW. 

  The HIGH setting detects more SQL injection attacks, and is the recommended setting. Due to the higher sensitivity, this setting generates more false positives, especially if your web requests typically contain unusual strings. During your protection pack (web ACL) testing and tuning, you might need to do more work to mitigate false positives. For information, see [Testing and tuning your AWS WAF protections](web-acl-testing.md). 

  The lower setting provides less stringent SQL injection detection, which also results in fewer false positives. LOW can be a better choice for resources that have other protections against SQL injection attacks or that have a low tolerance for false positives. 

## Where to find this rule statement
<a name="sqli-match-where-to-find"></a>
+ **Rule builder** on the console – For **Match type**, choose **Attack match condition** > **Contains SQL injection attacks**.
+ **API** – [SqliMatchStatement](https://docs.aws.amazon.com/waf/latest/APIReference/API_SqliMatchStatement.html)

# String match rule statement
<a name="waf-rule-statement-type-string-match"></a>

This section explains what a string match statement is and how it works.

A string match statement indicates the string that you want AWS WAF to search for in a request, where in the request to search, and how. For example, you can look for a specific string at the start of any query string in the request or as an exact match for the request's `User-agent` header. Usually, the string consists of printable ASCII characters, but you can use any character from hexadecimal 0x00 to 0xFF (decimal 0 to 255). 

## Rule statement characteristics
<a name="string-match-characteristics"></a>

**Nestable** – You can nest this statement type. 

**WCUs** – The base cost depends on the type of match that you use.
+ **Exactly matches string** – 2 
+ **Starts with string** – 2 
+ **Ends with string** – 2 
+ **Contains string** – 10 
+ **Contains word** – 10 

If you use the request component **All query parameters**, add 10 WCUs. If you use the request component **JSON body**, double the base cost WCUs. For each **Text transformation** that you apply, add 10 WCUs.

This statement type operates on a web request component, and requires the following request component settings: 
+ **Request component** – The part of the web request to inspect, for example, a query string or the body.
**Warning**  
If you inspect the request components **Body**, **JSON body**, **Headers**, or **Cookies**, read about the limitations on how much content AWS WAF can inspect at [Oversize web request components in AWS WAF](waf-oversize-request-components.md). 

  For information about web request components, see [Adjusting rule statement settings in AWS WAF](waf-rule-statement-fields.md).
+ **Optional text transformations** – Transformations that you want AWS WAF to perform on the request component before inspecting it. For example, you could transform to lowercase or normalize white space. If you specify more than one transformation, AWS WAF processes them in the order listed. For information, see [Using text transformations in AWS WAF](waf-rule-statement-transformation.md).

Additionally, this statement requires the following settings: 
+ **String to match** – This is the string that you want AWS WAF to compare to the specified request component. Usually, the string consists of printable ASCII characters, but you can use any character from hexadecimal 0x00 to 0xFF (decimal 0 to 255).
+ **String match condition** – This indicates the search type that you want AWS WAF to perform. 
  + **Exactly matches string** – The string and the value of the request component are identical.
  + **Starts with string** – The string appears at the beginning of the request component. 
  + **Ends with string** – The string appears at the end of the request component. 
  + **Contains string** – The string appears anywhere in the request component. 
  + **Contains word** – The string that you specify must appear in the request component. 

    For this option, the string that you specify must contain only alphanumeric characters or underscore (A-Z, a-z, 0-9, or \$1). 

    One of the following must be true for the request to match: 
    + The string exactly matches the value of the request component, such as the value of a header.
    + The string is at the beginning of the request component and is followed by a character other than an alphanumeric character or underscore (\$1), for example, `BadBot;`.
    + The string is at the end of the request component and is preceded by a character other than an alphanumeric character or underscore (\$1), for example, `;BadBot`.
    + The string is in the middle of the request component and is preceded and followed by characters other than alphanumeric characters or underscore (\$1), for example, `-BadBot;`.

## Where to find this rule statement
<a name="string-match-where-to-find"></a>
+ **Rule builder** on the console – For **Match type**, choose **String match condition**, and then fill in the strings that you want to match against.
+ **API** – [ByteMatchStatement](https://docs.aws.amazon.com/waf/latest/APIReference/API_ByteMatchStatement.html)

# Cross-site scripting attack rule statement
<a name="waf-rule-statement-type-xss-match"></a>

This section explains what an XSS (cross-site scripting) attack statement is and how it works.

An XSS attack statement inspects for malicious scripts in a web request component. In an XSS attack, the attacker uses vulnerabilities in a benign website as a vehicle to inject malicious client-site scripts into other legitimate web browsers. 

## Rule statement characteristics
<a name="xss-match-characteristics"></a>

**Nestable** – You can nest this statement type. 

**WCUs** – 40 WCUs, as a base cost. If you use the request component **All query parameters**, add 10 WCUs. If you use the request component **JSON body**, double the base cost WCUs. For each **Text transformation** that you apply, add 10 WCUs.

This statement type operates on a web request component, and requires the following request component settings: 
+ **Request component** – The part of the web request to inspect, for example, a query string or the body.
**Warning**  
If you inspect the request components **Body**, **JSON body**, **Headers**, or **Cookies**, read about the limitations on how much content AWS WAF can inspect at [Oversize web request components in AWS WAF](waf-oversize-request-components.md). 

  For information about web request components, see [Adjusting rule statement settings in AWS WAF](waf-rule-statement-fields.md).
+ **Optional text transformations** – Transformations that you want AWS WAF to perform on the request component before inspecting it. For example, you could transform to lowercase or normalize white space. If you specify more than one transformation, AWS WAF processes them in the order listed. For information, see [Using text transformations in AWS WAF](waf-rule-statement-transformation.md).

## Where to find this rule statement
<a name="xss-match-where-to-find"></a>
+ **Rule builder** on the console – For **Match type**, choose **Attack match condition** > **Contains XSS injection attacks**.
+ **API** – [XssMatchStatement](https://docs.aws.amazon.com/waf/latest/APIReference/API_XssMatchStatement.html)

# Using logical rule statements in AWS WAF
<a name="waf-rule-statements-logical"></a>

This section explains what a logical rule statement is and how it works.

Use logical rules statements to combine other statements or negate their results. Every logical rule statement takes at least one nested statement.

To logically combine or negate rule statement results, you nest the statements under logical rule statements. 

Logical rules statements are nestable. You can nest them inside other logical rule statements and use them in scope-down statements. For information about scope-down statements, see [Using scope-down statements in AWS WAF](waf-rule-scope-down-statements.md).

**Note**  
The visual editor on the console supports one level of rule statement nesting, which works for many needs. To nest more levels, edit the JSON representation of the rule on the console or use the APIs. 

This table describes the logical rule statements and provides guidelines for calculating protection pack (web ACL) capacity units (WCU) usage for each. For information about WCUs, see [Web ACL capacity units (WCUs) in AWS WAF](aws-waf-capacity-units.md). 


| Logical Statement  | Description | WCUs | 
| --- | --- | --- | 
| [AND logic](waf-rule-statement-type-and.md) | Combines nested statements with AND logic. | Based on nested statements | 
|  [NOT logic](waf-rule-statement-type-not.md)  |  Negates the results of a nested statement.  |  Based on nested statement  | 
| [OR logic](waf-rule-statement-type-or.md) | Combines nested statements with OR logic. | Based on nested statements | 

# AND rule statement
<a name="waf-rule-statement-type-and"></a>

The AND rule statement combines nested statements with a logical AND operation, so all nested statements must match for the AND statement to match. This requires at least two nested statements. 

## Rule statement characteristics
<a name="and-rule-statement-characteristics"></a>

**Nestable** – You can nest this statement type. 

**WCUs** – Depends on the nested statements.

## Where to find this rule statement
<a name="and-rule-statement-where-to-find"></a>
+ **Rule builder** on the console – For **If a request**, choose **matches all the statements (AND)**, and then fill in the nested statements. 
+ **API** – [AndStatement](https://docs.aws.amazon.com/waf/latest/APIReference/API_AndStatement.html)

## Examples
<a name="and-rule-statement-examples"></a>

The following listing shows the use of AND and NOT logical rule statements to eliminate false positives from the matches for an SQL injection attack statement. For this example, suppose we can write a single byte match statement to match the requests that are resulting in false positives. 

The AND statement matches for requests that do not match the byte match statement and that do match the SQL injection attack statement. 

```
{
      "Name": "SQLiExcludeFalsePositives",
      "Priority": 0,
      "Statement": {
        "AndStatement": {
          "Statements": [
            {
              "NotStatement": {
                "Statement": {
                  "ByteMatchStatement": {
                    "SearchString": "string identifying a false positive",
                    "FieldToMatch": {
                      "Body": {
                        "OversizeHandling": "MATCH"
                      }
                    },
                    "TextTransformations": [
                      {
                        "Priority": 0,
                        "Type": "NONE"
                      }
                    ],
                    "PositionalConstraint": "CONTAINS"
                  }
                }
              }
            },
            {
              "SqliMatchStatement": {
                "FieldToMatch": {
                  "Body": {
                    "OversizeHandling": "MATCH"
                  }
                },
                "TextTransformations": [
                  {
                    "Priority": 0,
                    "Type": "NONE"
                  }
                ]
              }
            }
          ]
        }
      },
      "Action": {
        "Block": {}
      },
      "VisibilityConfig": {
        "SampledRequestsEnabled": true,
        "CloudWatchMetricsEnabled": true,
        "MetricName": "SQLiExcludeFalsePositives"
      }
    }
```

Using the console rule visual editor, you can nest a non-logical statement or a NOT statement under an OR or AND statement. The nesting of the NOT statement is shown in the prior example. 

Using the console rule visual editor, you can nest most nestable statements under a logical rule statement, such as the one shown in the prior example. You can't use the visual editor to nest OR or AND statements. To configure this type of nesting, you need to provide your rule statement in JSON. For example, the following JSON rule listing includes an OR statement nested inside an AND statement. 

```
{
  "Name": "match_rule",
  "Priority": 0,
  "Statement": {
    "AndStatement": {
      "Statements": [
        {
          "LabelMatchStatement": {
            "Scope": "LABEL",
            "Key": "awswaf:managed:aws:bot-control:bot:category:monitoring"
          }
        },
        {
          "NotStatement": {
            "Statement": {
              "LabelMatchStatement": {
                "Scope": "LABEL",
                "Key": "awswaf:managed:aws:bot-control:bot:name:pingdom"
              }
            }
          }
        },
        {
          "OrStatement": {
            "Statements": [
              {
                "GeoMatchStatement": {
                  "CountryCodes": [
                    "JM",
                    "JP"
                  ]
                }
              },
              {
                "ByteMatchStatement": {
                  "SearchString": "JCountryString",
                  "FieldToMatch": {
                    "Body": {}
                  },
                  "TextTransformations": [
                    {
                      "Priority": 0,
                      "Type": "NONE"
                    }
                  ],
                  "PositionalConstraint": "CONTAINS"
                }
              }
            ]
          }
        }
      ]
    }
  },
  "Action": {
    "Block": {}
  },
  "VisibilityConfig": {
    "SampledRequestsEnabled": true,
    "CloudWatchMetricsEnabled": true,
    "MetricName": "match_rule"
  }
}
```

# NOT rule statement
<a name="waf-rule-statement-type-not"></a>

The NOT rule statement logically negates the results of a single nested statement, so the nested statements must not match for the NOT statement to match, and vice versa. This requires one nested statement. 

For example, if you want to block requests that don't originate in a specific country, create a NOT statement with action set to block, and nest a geographic match statement that specifies the country. 

## Rule statement characteristics
<a name="not-rule-statement-characteristics"></a>

**Nestable** – You can nest this statement type. 

**WCUs** – Depends on the nested statement.

## Where to find this rule statement
<a name="not-rule-statement-where-to-find"></a>
+ **Rule builder** on the console – For **If a request**, choose **doesn't match the statement (NOT)**, and then fill in the nested statement.
+ **API** – [NotStatement](https://docs.aws.amazon.com/waf/latest/APIReference/API_NotStatement.html)

# OR rule statement
<a name="waf-rule-statement-type-or"></a>

The OR rule statement combines nested statements with OR logic, so one of the nested statements must match for the OR statement to match. This requires at least two nested statements. 

For example, if you want to block requests that come from a specific country or that contain a specific query string, you could create an OR statement and nest in it a geo match statement for the country and a string match statement for the query string. 

If instead you want to block requests that *don't* come from a specific country or that contain a specific query string, you would modify the previous OR statement to nest the geo match statement one level lower, inside a NOT statement. This level of nesting requires you to use the JSON formatting, because the console supports only one level of nesting.

## Rule statement characteristics
<a name="or-rule-statement-characteristics"></a>

**Nestable** – You can nest this statement type. 

**WCUs** – Depends on the nested statements.

## Where to find this rule statement
<a name="or-rule-statement-where-to-find"></a>
+ **Rule builder** on the console – For **If a request**, choose **matches at least one of the statements (OR)**, and then fill in the nested statements. 
+ **API** – [OrStatement](https://docs.aws.amazon.com/waf/latest/APIReference/API_OrStatement.html)

**Examples**  
The following listing shows the use of OR to combine two other statements. The OR statement is a match if either of the nested statements match. 

```
{
  "Name": "neitherOfTwo",
  "Priority": 1,
  "Action": {
    "Block": {}
  },
  "VisibilityConfig": {
    "SampledRequestsEnabled": true,
    "CloudWatchMetricsEnabled": true,
    "MetricName": "neitherOfTwo"
  },
  "Statement": {
    "OrStatement": {
      "Statements": [
        {
          "GeoMatchStatement": {
            "CountryCodes": [
              "CA"
            ]
          }
        },
        {
          "IPSetReferenceStatement": {
            "ARN": "arn:aws:wafv2:us-east-1:111111111111:regional/ipset/test-ip-set-22222222/33333333-4444-5555-6666-777777777777"
          }
        }
      ]
    }
  }
}
```

Using the console rule visual editor, you can nest most nestable statements under a logical rule statement, but you can't use the visual editor to nest OR or AND statements. To configure this type of nesting, you need to provide your rule statement in JSON. For example, the following JSON rule listing includes an OR statement nested inside an AND statement. 

```
{
  "Name": "match_rule",
  "Priority": 0,
  "Statement": {
    "AndStatement": {
      "Statements": [
        {
          "LabelMatchStatement": {
            "Scope": "LABEL",
            "Key": "awswaf:managed:aws:bot-control:bot:category:monitoring"
          }
        },
        {
          "NotStatement": {
            "Statement": {
              "LabelMatchStatement": {
                "Scope": "LABEL",
                "Key": "awswaf:managed:aws:bot-control:bot:name:pingdom"
              }
            }
          }
        },
        {
          "OrStatement": {
            "Statements": [
              {
                "GeoMatchStatement": {
                  "CountryCodes": [
                    "JM",
                    "JP"
                  ]
                }
              },
              {
                "ByteMatchStatement": {
                  "SearchString": "JCountryString",
                  "FieldToMatch": {
                    "Body": {}
                  },
                  "TextTransformations": [
                    {
                      "Priority": 0,
                      "Type": "NONE"
                    }
                  ],
                  "PositionalConstraint": "CONTAINS"
                }
              }
            ]
          }
        }
      ]
    }
  },
  "Action": {
    "Block": {}
  },
  "VisibilityConfig": {
    "SampledRequestsEnabled": true,
    "CloudWatchMetricsEnabled": true,
    "MetricName": "match_rule"
  }
}
```

# Using rate-based rule statements in AWS WAF
<a name="waf-rule-statement-type-rate-based"></a>

This section explains what a rate-based rule statement is and how it works.

A rate-based rule counts incoming requests and rate limits requests when they are coming at too fast a rate. The rule aggregates requests according to your criteria, and counts and rate limits the aggregate groupings, based on the rule's evaluation window, request limit, and action settings. 

**Note**  
You can also rate limit web requests using the targeted protection level of the Bot Control AWS Managed Rules rule group. Using this managed rule group incurs additional fees. For more information, see [Options for rate limiting in rate-based rules and targeted Bot Control rules](waf-rate-limiting-options.md). 

AWS WAF tracks and manages web requests separately for each instance of a rate-based rule that you use. For example, if you provide the same rate-based rule settings in two web ACLs, each of the two rule statements represents a separate instance of the rate-based rule and each gets its own tracking and management by AWS WAF. If you define a rate-based rule inside a rule group, and then use that rule group in multiple places, each use creates a separate instance of the rate-based rule that gets its own tracking and management by AWS WAF.

**Not nestable** – You can't nest this statement type inside other statements. You can include it directly in a protection pack (web ACL) or rule group. 

**Scope-down statement** – This rule type can take a scope-down statement, to narrow the scope of the requests that the rule tracks and rate limits. The scope-down statement can be optional or required, depending on your other rule configuration settings. The details are covered in this section. For general information about scope-down statements, see [Using scope-down statements in AWS WAF](waf-rule-scope-down-statements.md). 

**WCUs** – 2, as a base cost. For each custom aggregation key that you specify, add 30 WCUs. If you use a scope-down statement in the rule, calculate and add the WCUs for that.

**Where to find this rule statement**
+ **Rule builder** in your protection pack (web ACL), on the console – Under **Rule**, for **Type**, choose **Rate-based rule**.
+ **API** – [RateBasedStatement](https://docs.aws.amazon.com/waf/latest/APIReference/API_RateBasedStatement.html)

**Topics**
+ [

# Rate-based rule high-level settings in AWS WAF
](waf-rule-statement-type-rate-based-high-level-settings.md)
+ [

# Rate-based rule caveats in AWS WAF
](waf-rule-statement-type-rate-based-caveats.md)
+ [

# Aggregating rate-based rules in AWS WAF
](waf-rule-statement-type-rate-based-aggregation-options.md)
+ [

# Rate-based rule aggregation instances and counts
](waf-rule-statement-type-rate-based-aggregation-instances.md)
+ [

# Applying rate limiting to requests in AWS WAF
](waf-rule-statement-type-rate-based-request-limiting.md)
+ [

# Rate-based rule examples in AWS WAF
](waf-rule-statement-type-rate-based-examples.md)
+ [

# Listing IP addresses that are being rate limited by rate-based rules
](listing-managed-ips.md)

# Rate-based rule high-level settings in AWS WAF
<a name="waf-rule-statement-type-rate-based-high-level-settings"></a>

A rate-based rule statement uses the following high level settings: 
+ **Evaluation window** – The amount of time, in seconds, that AWS WAF should include in its request counts, looking back from the current time. For example, for a setting of 120, when AWS WAF checks the rate, it counts the requests for the 2 minutes immediately preceding the current time. Valid settings are 60 (1 minute), 120 (2 minutes), 300 (5 minutes), and 600 (10 minutes), and 300 (5 minutes) is the default. 

  This setting doesn't determine how often AWS WAF checks the rate, but how far back it looks each time it checks. AWS WAF checks the rate frequently, with timing that's independent of the evaluation window setting. 
+ **Rate limit** – The maximum number of requests matching your criteria that AWS WAF should just track for the specified evaluation window. The lowest limit setting allowed is 10. When this limit is breached, AWS WAF applies the rule action setting to additional requests matching your criteria. 

  AWS WAF applies rate limiting near the limit that you set, but does not guarantee an exact limit match. For more information, see [Rate-based rule caveats](waf-rule-statement-type-rate-based-caveats.md). 
+ **Request aggregation** – The aggregation criteria to use on the web requests that the rate-based rule counts and rate limits. The rate limit that you set applies to each aggregation instance. For details, see [Aggregating rate-based rules](waf-rule-statement-type-rate-based-aggregation-options.md) and [Aggregation instances and counts](waf-rule-statement-type-rate-based-aggregation-instances.md). 
+ **Action** – The action to take on requests that the rule rate limits. You can use any rule action except Allow. This is set at the rule level as usual, but has some restrictions and behaviors that are specific to rate-based rules. For general information about rule actions, see [Using rule actions in AWS WAF](waf-rule-action.md). For information specific to rate limiting, see [Applying rate limiting to requests in AWS WAF](waf-rule-statement-type-rate-based-request-limiting.md) in this section.
+ **Scope of inspection and rate limiting** – You can narrow the scope of the requests that the rate-based statement tracks and rate limits by adding a scope-down statement. If you specify a scope-down statement, the rule only aggregates, counts, and rate limits requests that match the scope-down statement. If you choose the request aggregation option **Count all**, then the scope-down statement is required. For more information about scope-down statements, see [Using scope-down statements](waf-rule-scope-down-statements.md). 
+ **(Optional) Forwarded IP configuration** – This is only used if you specify **IP address in header** in your request aggregation, either alone or as part of the custom keys settings. AWS WAF retrieves the first IP address in the specified header and uses that as the aggregation value. A common header for this purpose is `X-Forwarded-For`, but you can specify any header. For more information, see [Using forwarded IP addresses](waf-rule-statement-forwarded-ip-address.md). 

# Rate-based rule caveats in AWS WAF
<a name="waf-rule-statement-type-rate-based-caveats"></a>

This section lists the caveats for using rate-based rules.

AWS WAF rate limiting is designed to control high request rates and protect your application's availability in the most efficient and effective way possible. It's not intended for precise request-rate limiting. 
+ AWS WAF estimates the current request rate using an algorithm that gives more importance to more recent requests. Because of this, AWS WAF will apply rate limiting near the limit that you set, but does not guarantee an exact limit match. 
+ Each time that AWS WAF estimates the rate of requests, AWS WAF looks back at the number of requests that came in during the configured evaluation window. Due to this and other factors such as propagation delays, it's possible for requests to be coming in at too high a rate for up to several minutes before AWS WAF detects and rate limits them. Similarly. the request rate can be below the limit for a period of time before AWS WAF detects the decrease and discontinues the rate limiting action. Usually, this delay is below 30 seconds.
+ If you change any of the rate limit settings in a rule that's in use, the change resets the rule's rate limiting counts. This can pause the rule's rate limiting activities for up to a minute. The rate limit settings are the evaluation window, rate limit, request aggregation settings, forwarded IP configuration, and scope of inspection. 

# Aggregating rate-based rules in AWS WAF
<a name="waf-rule-statement-type-rate-based-aggregation-options"></a>

This section explains your options for aggregating requests.

By default, a rate-based rule aggregates and rate limits requests based on the request IP address. You can configure the rule to use various other aggregation keys and key combinations. For example, you can aggregate based on a forwarded IP address, on the HTTP method, or on a query argument. You can also specify aggregation key combinations, such as IP address and HTTP method, or the values of two different cookies. 

**Note**  
All of the request components that you specify in the aggregation key must be present in a web request for the request to be evaluated or rate limited by the rule. 

You can configure your rate-based rule with the following aggregation options. 
+ **Source IP address** – Aggregate using only the IP address from the web request origin. 

  The source IP address might not contain the address of the originating client. If a web request goes through one or more proxies or load balancers, this will contain the address of the last proxy. 
+ **IP address in header** – Aggregate using only a client address in an HTTP header. This is also referred to as a forwarded IP address. 

  With this configuration, you also specify a fallback behavior to apply to a web request with a malformed IP address in the header. The fallback behavior sets the matching result for the request, to match or no match. For no match, the rate-based rule doesn't count or rate limit the request. For match, the rate-based rule groups the request together with other requests that have a malformed IP address in the specified header. 

  Use caution with this option, because headers can be handled inconsistently by proxies and they can also be modified to bypass inspection. For additional information and best practices, see [Using forwarded IP addresses in AWS WAF](waf-rule-statement-forwarded-ip-address.md).
+ **ASN** – Aggregate using an Autonomous System Number (ASN) associated with the source IP address as an aggregate key. This might not be the address of the originating client. If a web request goes through one or more proxies or load balancers, this contains the address of the last proxy. 

  If AWS WAF can’t derive an ASN from the IP address, it counts the ASN as ASN 0. If you don't want to apply rate limiting to unmapped ASNs, you can create a scope-down rule that excludes requests with ASN 0.
+ **ASN in header** – Aggregate using an ASN associated with a client IP address in an HTTP header. This is also referred to as a forwarded IP address. With this configuration, you also specify a fallback behavior to apply to a web request with an invalid or malformed IP address. The fallback behavior sets the matching result for the request, to match or no match. If you set the fallback behavior to match in the forwarded IP configuration, AWS WAF treats the invalid IP address as a matching value. This allows AWS WAF to continue evaluating any remaining parts of your rate-based rule's composite key. For no match, the rate-based rule doesn't count or rate limit the request. 

  Use caution with this option, as headers can be handled inconsistently by proxies and they can be modified to bypass inspection. For additional information and best practices, see [Using forwarded IP addresses in AWS WAF](waf-rule-statement-forwarded-ip-address.md).
+ **Count all** – Count and rate limit all requests that match the rule's scope-down statement. This option requires a scope-down statement. This is typically used to rate limit a specific set of requests, such as all requests with a specific label or all requests from a specific geographic area. 
+ **Custom keys** – Aggregate using one or more custom aggregation keys. To combine either of the IP address options with other aggregation keys, define them here under custom keys. 

  Custom aggregation keys are a subset of the web request component options described at [Request components in AWS WAF](waf-rule-statement-fields-list.md).

  The key options are the following. Except where noted, you can use an option multiple times, for example, two headers or three label namespaces.
  + **Label namespace** – Use a label namespace as an aggregation key. Each distinct fully qualified label name that has the specified label namespace contributes to the aggregation instance. If you use just one label namespace as your custom key, then each label name fully defines an aggregation instance.

    The rate-based rule uses only labels that have been added to the request by rules that are evaluated beforehand in the protection pack (web ACL).

    For information about label namespaces and names, see [Label syntax and naming requirements in AWS WAF](waf-rule-label-requirements.md).
  + **Header** – Use a named header as an aggregation key. Each distinct value in the header contributes to the aggregation instance. 

    Header takes an optional text transformation. See [Using text transformations in AWS WAF](waf-rule-statement-transformation.md). 
  + **Cookie** – Use a named cookie as an aggregation key. Each distinct value in the cookie contributes to the aggregation instance. 

    Cookie takes an optional text transformation. See [Using text transformations in AWS WAF](waf-rule-statement-transformation.md). 
  + **Query argument** – Use a single query argument in the request as an aggregate key. Each distinct value for the named query argument contributes to the aggregation instance. 

    Query argument takes an optional text transformation. See [Using text transformations in AWS WAF](waf-rule-statement-transformation.md). 
  + **Query string** – Use the entire query string in the request as an aggregate key. Each distinct query string contributes to the aggregation instance. You can use this key type once. 

    Query string takes an optional text transformation. See [Using text transformations in AWS WAF](waf-rule-statement-transformation.md). 
  + **URI path** – Use the URI path in the request as an aggregate key. Each distinct URI path contributes to the aggregation instance. You can use this key type once. 

    URI path takes an optional text transformation. See [Using text transformations in AWS WAF](waf-rule-statement-transformation.md). 
  + **JA3 fingerprint** – Use the JA3 fingerprint in the request as an aggregate key. Each distinct JA3 fingerprint contributes to the aggregation instance. You can use this key type once. 
  + **JA4 fingerprint** – Use the JA4 fingerprint in the request as an aggregate key. Each distinct JA4 fingerprint contributes to the aggregation instance. You can use this key type once. 
  + **HTTP method** – Use the request's HTTP method as an aggregate key. Each distinct HTTP method contributes to the aggregation instance. You can use this key type once. 
  + **IP address** – Aggregate using the IP address from the web request origin in combination with other keys.

    This might not contain the address of the originating client. If a web request goes through one or more proxies or load balancers, this will contain the address of the last proxy. 
  + **IP address in header** – Aggregate using the client address in an HTTP header in combination with other keys. This is also referred to as a forwarded IP address. 

    Use caution with this option, as headers can be handled inconsistently by proxies and they can be modified to bypass inspection. For additional information and best practices, see [Using forwarded IP addresses in AWS WAF](waf-rule-statement-forwarded-ip-address.md).

# Rate-based rule aggregation instances and counts
<a name="waf-rule-statement-type-rate-based-aggregation-instances"></a>

This section explains how a rate-based rule evaluates web requests.

When a rate-based rule evaluates web requests using your aggregation criteria, each unique set of values that the rule finds for the specified aggregation keys defines a unique *aggregation instance*. 
+ **Multiple keys** – If you've defined multiple custom keys, the value for each key contributes to the aggregation instance definition. Each unique combination of values defines an aggregation instance. 
+ **Single key** – If you've chosen a single key, either in the custom keys or by selecting one of the singleton IP address choices, then each unique value for the key defines an aggregation instance. 
+ **Count all - no keys** – If you've selected the aggregation option **Count all**, then all requests that the rule evaluates belong to a single aggregation instance for the rule. This choice requires a scope-down statement.

 

A rate-based rule counts web requests separately for each aggregation instance that it identifies. 

For example, assume a rate-based rule evaluates web requests with the following IP address and HTTP method values: 
+ IP address 10.1.1.1, HTTP method POST
+ IP address 10.1.1.1, HTTP method GET
+ IP address 127.0.0.0, HTTP method POST
+ IP address 10.1.1.1, HTTP method GET

The rule creates different aggregation instances according to your aggregation criteria. 
+ If the aggregation criteria is just the IP address, then each individual IP address is an aggregation instance, and AWS WAF counts requests separately for each. The aggregation instances and request counts for our example would be the following: 
  + IP address 10.1.1.1: count 3
  + IP address 127.0.0.0: count 1
+ If the aggregation criteria is HTTP method, then each individual HTTP method is an aggregation instance. The aggregation instances and request counts for our example would be the following: 
  + HTTP method POST: count 2
  + HTTP method GET: count 2
+ If the aggregation criteria is IP address and HTTP method, then each IP address and each HTTP method would contribute to the combined aggregation instance. The aggregation instances and request counts for our example would be the following: 
  + IP address 10.1.1.1, HTTP method POST: count 1
  + IP address 10.1.1.1, HTTP method GET: count 2
  + IP address 127.0.0.0, HTTP method POST: count 1

# Applying rate limiting to requests in AWS WAF
<a name="waf-rule-statement-type-rate-based-request-limiting"></a>

This section explains how rate limiting behavior works for rate-based rules.

The criteria that AWS WAF uses to rate limit requests for a rate-based rule is the same criteria that AWS WAF uses to aggregate requests for the rule. If you define a scope-down statement for the rule, AWS WAF only aggregates, counts, and rate limits requests that match the scope-down statement. 

The match criteria that causes a rate-based rule to apply its rule action settings to a specific web request are as follows: 
+ The web request matches the rule's scope-down statement, if one is defined.
+ The web request belongs to an aggregation instance whose request count is currently over the rule's limit. 

**How AWS WAF applies the rule action**  
When a rate-based rule applies rate limiting to a request, it applies the rule action and, if you've defined any custom handling or labeling in your action specification, the rule applies those. This request handling is the same as the way a match rule applies its action settings to matching web requests. A rate-based rule only applies labels or performs other actions on requests that it is actively rate limiting. 

You can use any rule action except Allow. For general information about rule actions, see [Using rule actions in AWS WAF](waf-rule-action.md). 

The following list describes how rate limiting works for each of the actions.
+ **Block** – AWS WAF blocks the request and applies any custom blocking behavior that you've defined. 
+ **Count** – AWS WAF counts the request, applies any custom headers or labels that you've defined, and continues the protection pack (web ACL) evaluation of the request. 

  This action doesn't limit the rate of requests. It just counts the requests that are over the limit.
+ **CAPTCHA or Challenge** – AWS WAF handles the request either like a Block or like a Count, depending on the state of the request's token. 

  This action doesn't limit the rate of requests that have valid tokens. It limits the rate of requests that are over the limit and are also missing valid tokens.
  + If the request doesn't have a valid, unexpired token, the action blocks the request and sends the CAPTCHA puzzle or the browser challenge back to the client. 

    If the end user or client browser responds successfully, the client receives a valid token and it automatically resends the original request. If rate limiting for the aggregation instance is still in effect, this new request with the valid, unexpired token will have the action applied to it as described in the next bullet point.
  + If the request has a valid, unexpired token, the CAPTCHA or Challenge action verifies the token and takes no action on the request, similar to the Count action. The rate-based rule returns the request evaluation back to the protection pack (web ACL) without taking any terminating action, and the protection pack (web ACL) continues its evaluation of the request.

  For additional information, see [CAPTCHA and Challenge in AWS WAF](waf-captcha-and-challenge.md).

**If you rate limit only the IP address or forwarded IP address**  
When you configure the rule to rate limit only IP address for forwarded IP address, you can retrieve the list of IP addresses that the rule is currently rate limiting. If you're using a scope-down statement, the requests that are rate limited are only those in the IP list that match the scope-down statement. For information about retrieving the IP address list, see [Listing IP addresses that are being rate limited by rate-based rules](listing-managed-ips.md).

# Rate-based rule examples in AWS WAF
<a name="waf-rule-statement-type-rate-based-examples"></a>

This section describes example configurations for a variety of common rate-based rules use cases. 

Each example provides a description of the use case and then shows the solution in JSON listings for the custom configured rules. 

**Note**  
The JSON listings shown in these examples were created in the console by configuring the rule and then editing it using the **Rule JSON editor**. 

**Topics**
+ [

# Rate limit the requests to a login page
](waf-rate-based-example-limit-login-page.md)
+ [

# Rate limit the requests to a login page from any IP address, user agent pair
](waf-rate-based-example-limit-login-page-keys.md)
+ [

# Rate limit the requests that are missing a specific header
](waf-rate-based-example-limit-missing-header.md)
+ [

# Rate limit the requests with specific labels
](waf-rate-based-example-limit-labels.md)
+ [

# Rate limit the requests for labels that have a specified label namespace
](waf-rate-based-example-limit-label-aggregation.md)
+ [

# Rate limit the requests with specific ASNs
](waf-rate-based-example-limit-asn.md)

# Rate limit the requests to a login page
<a name="waf-rate-based-example-limit-login-page"></a>

To limit the number of requests to the login page on your website without affecting traffic to the rest of your site, you could create a rate-based rule with a scope-down statement that matches requests to your login page and with the request aggregation set to **Count all**. 

The rate-based rule will count all requests for the login page in a single aggregation instance and apply the rule action to all requests matching the scope-down statement when the requests exceed the limit.

The following JSON listing shows an example of this rule configuration. The count all aggregation option is listed in the JSON as the setting `CONSTANT`. This example matches login pages that start with `/login`. 

```
{
  "Name": "test-rbr",
  "Priority": 0,
  "Action": {
    "Block": {}
  },
  "VisibilityConfig": {
    "SampledRequestsEnabled": true,
    "CloudWatchMetricsEnabled": true,
    "MetricName": "test-rbr"
  },
  "Statement": {
    "RateBasedStatement": {
      "Limit": 1000,
      "EvaluationWindowSec": 300,
      "AggregateKeyType": "CONSTANT",
      "ScopeDownStatement": {
        "ByteMatchStatement": {
          "FieldToMatch": {
            "UriPath": {}
          },
          "PositionalConstraint": "STARTS_WITH",
          "SearchString": "/login",
          "TextTransformations": [
            {
              "Type": "NONE",
              "Priority": 0
            }
          ]
        }
      }
    }
  }
}
```

# Rate limit the requests to a login page from any IP address, user agent pair
<a name="waf-rate-based-example-limit-login-page-keys"></a>

To limit the number of requests to the login page on your website for IP address, user agent pairs that exceed your limit, set the request aggregation to **Custom keys** and provide the aggregation criteria. 

The following JSON listing shows an example of this rule configuration. In this example, we've set the limit to 100 requests in any five minute period per IP address, user agent pair. 

```
{
  "Name": "test-rbr",
  "Priority": 0,
  "Action": {
    "Block": {}
  },
  "VisibilityConfig": {
    "SampledRequestsEnabled": true,
    "CloudWatchMetricsEnabled": true,
    "MetricName": "test-rbr"
  },
  "Statement": {
    "RateBasedStatement": {
      "Limit": 100,
      "EvaluationWindowSec": 300,
      "AggregateKeyType": "CUSTOM_KEYS",
      "CustomKeys": [
        {
          "Header": {
            "Name": "User-Agent",
            "TextTransformations": [
              {
                "Priority": 0,
                "Type": "NONE"
              }
            ]
          }
        },
        {
          "IP": {}
        }
      ],
      "ScopeDownStatement": {
        "ByteMatchStatement": {
          "FieldToMatch": {
            "UriPath": {}
          },
          "PositionalConstraint": "STARTS_WITH",
          "SearchString": "/login",
          "TextTransformations": [
            {
              "Type": "NONE",
              "Priority": 0
            }
          ]
        }
      }
    }
  }
}
```

# Rate limit the requests that are missing a specific header
<a name="waf-rate-based-example-limit-missing-header"></a>

To limit the number of requests that are missing a specific header, you can use the **Count all** aggregation option with a scope-down statement. Configure the scope-down statement with a logical `NOT` statement containing a statement that returns true only if the header exists and has a value. 

The following JSON listing shows an example of this rule configuration. 

```
{
  "Name": "test-rbr",
  "Priority": 0,
  "Action": {
    "Block": {}
  },
  "VisibilityConfig": {
    "SampledRequestsEnabled": true,
    "CloudWatchMetricsEnabled": true,
    "MetricName": "test-rbr"
  },
  "Statement": {
    "RateBasedStatement": {
      "Limit": 1000,
      "AggregateKeyType": "CONSTANT",
      "EvaluationWindowSec": 300,
      "ScopeDownStatement": {
        "NotStatement": {
          "Statement": {
            "SizeConstraintStatement": {
              "FieldToMatch": {
                "SingleHeader": {
                  "Name": "user-agent"
                }
              },
              "ComparisonOperator": "GT",
              "Size": 0,
              "TextTransformations": [
                {
                  "Type": "NONE",
                  "Priority": 0
                }
              ]
            }
          }
        }
      }
    }
  }
}
```

# Rate limit the requests with specific labels
<a name="waf-rate-based-example-limit-labels"></a>

To limit the number of requests of various categories, you can combine rate limiting with any rule or rule group that add labels to requests. To do this, you configure your protection pack (web ACL) as follows: 
+ Add the rules or rule groups that add labels, and configure them so that they don't block or allow the requests that you want to rate limit. If you use managed rule groups, you might need to override some rule group rule actions to Count to achieve this behavior. 
+ Add a rate-based rule to your protection pack (web ACL) with a priority number setting that is higher than the labeling rules and rule groups. AWS WAF evaluates rules in numeric order, starting from the lowest, so your rate-based rule will run after the labeling rules. Configure your rate limiting on the labels using a combination of label matching in the rule's scope-down statement and label aggregation. 

The following example uses the Amazon IP reputation list AWS Managed Rules rule group. The rule group rule `AWSManagedIPDDoSList` detects and labels requests whose IPs are known to be actively engaging in DDoS activities. The rule's action is configured to Count in the rule group definition. For more information about the rule group, see [Amazon IP reputation list managed rule group](aws-managed-rule-groups-ip-rep.md#aws-managed-rule-groups-ip-rep-amazon).

The following protection pack (web ACL) JSON listing uses the IP reputation rule group followed by a label-matching rate-based rule. The rate-based rule uses a scope-down statement to filter for requests that have been marked by the rule group rule. The rate-based rule statement aggregates and rate limits the filtered requests by their IP addresses. 

```
{
  "Name": "test-web-acl",
  "Id": ... 
  "ARN": ...
  "DefaultAction": {
    "Allow": {}
  },
  "Description": "",
  "Rules": [
    {
      "Name": "AWS-AWSManagedRulesAmazonIpReputationList",
      "Priority": 0,
      "Statement": {
        "ManagedRuleGroupStatement": {
          "VendorName": "AWS",
          "Name": "AWSManagedRulesAmazonIpReputationList"
        }
      },
      "OverrideAction": {
        "None": {}
      },
      "VisibilityConfig": {
        "SampledRequestsEnabled": true,
        "CloudWatchMetricsEnabled": true,
        "MetricName": "AWS-AWSManagedRulesAmazonIpReputationList"
      }
    },
    {
      "Name": "test-rbr",
      "Priority": 1,
      "Statement": {
        "RateBasedStatement": {
          "Limit": 100,
          "EvaluationWindowSec": 300,
          "AggregateKeyType": "IP",
          "ScopeDownStatement": {
            "LabelMatchStatement": {
              "Scope": "LABEL",
              "Key": "awswaf:managed:aws:amazon-ip-list:AWSManagedIPDDoSList"
            }
          }
        }
      },
      "Action": {
        "Block": {}
      },
      "VisibilityConfig": {
        "SampledRequestsEnabled": true,
        "CloudWatchMetricsEnabled": true,
        "MetricName": "test-rbr"
      }
    }
  ],
  "VisibilityConfig": {
    "SampledRequestsEnabled": true,
    "CloudWatchMetricsEnabled": true,
    "MetricName": "test-web-acl"
  },
  "Capacity": 28,
  "ManagedByFirewallManager": false,
  "RetrofittedByFirewallManager": false,
  "LabelNamespace": "awswaf:0000000000:webacl:test-web-acl:"
}
```

# Rate limit the requests for labels that have a specified label namespace
<a name="waf-rate-based-example-limit-label-aggregation"></a>

**Note**  
The common level rules in the Bot Control managed rule group add labels for bots of various categories, but they only block requests from unverified bots. For information about these rules, see [Bot Control rules listing](aws-managed-rule-groups-bot.md#aws-managed-rule-groups-bot-rules).

If you use the Bot Control managed rule group, you can add rate limiting for requests from individual verified bots. To do this, you add a rate-based rule that runs after the Bot Control rule group and aggregates requests by their bot name labels. You specify the **Label namespace** aggregation key and set the namespace key to `awswaf:managed:aws:bot-control:bot:name:`. Each unique label with the specified namespace will define an aggregation instance. For example, the labels `awswaf:managed:aws:bot-control:bot:name:axios` and `awswaf:managed:aws:bot-control:bot:name:curl` each define an aggregation instance.

The following protection pack (web ACL) JSON listing shows this configuration. The rule in this example limits requests for any single bot aggregation instance to 1,000 in a two minute period. 

```
{
  "Name": "test-web-acl",
  "Id": ... 
  "ARN": ...
  "DefaultAction": {
    "Allow": {}
  },
  "Description": "",
  "Rules": [
    {
      "Name": "AWS-AWSManagedRulesBotControlRuleSet",
      "Priority": 0,
      "Statement": {
        "ManagedRuleGroupStatement": {
          "VendorName": "AWS",
          "Name": "AWSManagedRulesBotControlRuleSet",
          "ManagedRuleGroupConfigs": [
            {
              "AWSManagedRulesBotControlRuleSet": {
                "InspectionLevel": "COMMON"
              }
            }
          ]
        }
      },
      "OverrideAction": {
        "None": {}
      },
      "VisibilityConfig": {
        "SampledRequestsEnabled": true,
        "CloudWatchMetricsEnabled": true,
        "MetricName": "AWS-AWSManagedRulesBotControlRuleSet"
      }
    },
    {
      "Name": "test-rbr",
      "Priority": 1,
      "Statement": {
        "RateBasedStatement": {
          "Limit": 1000,
          "EvaluationWindowSec": 120,
          "AggregateKeyType": "CUSTOM_KEYS",
          "CustomKeys": [
            {
              "LabelNamespace": {
                "Namespace": "awswaf:managed:aws:bot-control:bot:name:"
              }
            }
          ]
        }
      },
      "Action": {
        "Block": {}
      },
      "VisibilityConfig": {
        "SampledRequestsEnabled": true,
        "CloudWatchMetricsEnabled": true,
        "MetricName": "test-rbr"
      }
    }
  ],
  "VisibilityConfig": {
    "SampledRequestsEnabled": true,
    "CloudWatchMetricsEnabled": true,
    "MetricName": "test-web-acl"
  },
  "Capacity": 82,
  "ManagedByFirewallManager": false,
  "RetrofittedByFirewallManager": false,
  "LabelNamespace": "awswaf:0000000000:webacl:test-web-acl:"
}
```

# Rate limit the requests with specific ASNs
<a name="waf-rate-based-example-limit-asn"></a>

To limit the number of requests from specific Autonomous System Numbers (ASNs) based on the IP address of the requests, set the request aggregation to *Custom keys* and provide the aggregation criteria.

The following JSON shows an example of a rule aggregating ASNs derived from forwarded IP addresses found in the `X-Forwarded-For` header. If AWS WAF can't derive an ASN because the IP address is malformed, the fallback behavior is set to `MATCH`.

```
{
    "Name": "test-rbr",
    "Priority": 0,
    "Statement": {
        "RateBasedStatement": {
            "AggregateKeyType": "CUSTOM_KEYS",
            "CustomKeys": [
                {
                    "ASN": {}
                },
                {
                    "ForwardedIP": {}
                }
            ],
            "EvaluationWindowSec": 300,
            "ForwardedIPConfig": {
                "FallbackBehavior": "MATCH",
                "HeaderName": "X-Forwarded-For"
            },
            "Limit": 2000
        }
    },
    "VisibilityConfig": {
        "CloudWatchMetricsEnabled": true,
        "MetricName": "test-rbr",
        "SampledRequestsEnabled": true
    }
}
```

# Listing IP addresses that are being rate limited by rate-based rules
<a name="listing-managed-ips"></a>

This section explains how to access the list of IP addresses that are currently rate-limited by a rate-based rule by using the CLI, the API, or any of the SDKs. 

If your rate-based rule only aggregates on IP address or forwarded IP address, you can retrieve the list of IP addresses that the rule is currently rate limiting. AWS WAF stores these IP addresses in the rule's managed keys list. 

**Note**  
This option is only available if you aggregate on only the IP address or only an IP address in a header. If you use the custom keys request aggregation, you can't retrieve a list of rate limited IP addresses, even if you use one of the IP address specifications in your custom keys.

A rate-based rule applies its rule action to requests from the rule's managed keys list that match the rule's scope-down statement. When a rule has no scope-down statement, it applies the action to all requests from the IP addresses that are in the list. The rule action is Block by default, but it can be any valid rule action except for Allow. The maximum number of IP addresses that AWS WAF can rate limit using a single rate-based rule instance is 10,000. If more than 10,000 addresses exceed the rate limit, AWS WAF limits those with the highest rates. 

You can access a rate-based rule's managed keys list using the CLI, the API, or any of the SDKs. This topic covers access using the CLI and APIs. The console doesn't provide access to the list at this time. 

For the AWS WAF API, the command is [GetRateBasedStatementManagedKeys](https://docs.aws.amazon.com/waf/latest/APIReference/API_GetRateBasedStatementManagedKeys.html).

For the AWS WAF CLI, the command is [get-rate-based-statement-managed-keys](https://docs.aws.amazon.com/cli/latest/reference/wafv2/get-rate-based-statement-managed-keys.html). 

The following shows the syntax for retrieving the list of rate limited IP addresses for a rate-based rule that's being used in a protection pack (web ACL) on an Amazon CloudFront distribution.

```
aws wafv2 get-rate-based-statement-managed-keys --scope=CLOUDFRONT --region=us-east-1 --web-acl-name=WebACLName --web-acl-id=WebACLId --rule-name=RuleName
```

The following shows the syntax for a regional application, an Amazon API Gateway REST API, an Application Load Balancer, an AWS AppSync GraphQL API, an Amazon Cognito user pool, an AWS App Runner service, AWS Amplify, or an AWS Verified Access instance. 

```
aws wafv2 get-rate-based-statement-managed-keys --scope=REGIONAL --region=region --web-acl-name=WebACLName --web-acl-id=WebACLId --rule-name=RuleName
```

AWS WAF monitors web requests and manages keys independently for each unique combination of protection pack (web ACL), optional rule group, and rate-based rule. For example, if you define a rate-based rule inside a rule group, and then use the rule group in a protection pack (web ACL), AWS WAF monitors web requests and manages keys for that protection pack (web ACL), rule group reference statement, and rate-based rule instance. If you use the same rule group in a second protection pack (web ACL), AWS WAF monitors web requests and manages keys for this second usage completely independent of your first.

For a rate-based rule that you've defined inside a rule group, you need to provide the name of the rule group reference statement in your request, in addition to the protection pack (web ACL) name and the name of the rate-based rule inside the rule group. The following shows the syntax for a regional application where the rate-based rule is defined inside a rule group, and the rule group is used in a protection pack (web ACL). 

```
aws wafv2 get-rate-based-statement-managed-keys --scope=REGIONAL --region=region --web-acl-name=WebACLName --web-acl-id=WebACLId --rule-group-rule-name=RuleGroupRuleName --rule-name=RuleName
```

# Using rule group rule statements in AWS WAF
<a name="waf-rule-statements-rule-group"></a>

**Note**  
Rule group rule statements are not nestable. 

This section describes the rule group rule statements that you can use in your protection pack (web ACL). Rule group protection pack (web ACL) capacity units (WCUs) are set by the rule group owner at the time of creation. For information about WCUs, see [Web ACL capacity units (WCUs) in AWS WAF](aws-waf-capacity-units.md). 


| Rule group statement | Description | WCUs | 
| --- | --- | --- | 
|  [Using managed rule group statements](waf-rule-statement-type-managed-rule-group.md)  |  Runs the rules that are defined in the specified managed rule group.  You can narrow the scope of requests that the rule group evaluates by adding a scope-down statement.  You can't nest a managed rule group statement inside any other statement type.  |  Defined by the rule group, plus any additional WCUs for a scope-down statement.  | 
| [Using rule group statements](waf-rule-statement-type-rule-group.md) | Runs the rules that are defined in a rule group that you manage.  You can't add a scope-down statement to a rule group reference statement for your own rule group.  You can't nest a rule group statement inside any other statement type  | You define the WCU limit for the rule group when you create it. | 

# Using managed rule group statements in AWS WAF
<a name="waf-rule-statement-type-managed-rule-group"></a>

This section explains how managed rule group rule statements work.

The managed rule group rule statement adds a reference in your protection pack (web ACL) rules list to a managed rule group. You don't see this option under your rule statements on the console, but when you work with the JSON format of your web ACL, any managed rule groups that you've added show up under the protection pack (web ACL) rules as this type.

A managed rule group is either an AWS Managed Rules rule group, most of which are free for AWS WAF customers, or an AWS Marketplace managed rule group. You automatically subscribe to the paid AWS Managed Rules rule groups when you add them to your protection pack (web ACL). You can subscribe to AWS Marketplace managed rule groups through AWS Marketplace. For more information, see [Using managed rule groups in AWS WAF](waf-managed-rule-groups.md).

When you add a rule group to a protection pack (web ACL), you can override the actions of rules in the group to Count or to another rule action. For more information, see [Overriding rule group actions in AWS WAF](web-acl-rule-group-override-options.md).

You can narrow the scope of the requests that AWS WAF evaluates with the rule group. To do this, you add a scope-down statement inside the rule group statement. For information about scope-down statements, see [Using scope-down statements in AWS WAF](waf-rule-scope-down-statements.md). This can help you manage how the rule group affects your traffic and can help you contain costs associated with traffic volume when you use the rule group. For information and examples for using scope-down statements with the AWS WAF Bot Control managed rule group, see [AWS WAF Bot Control](waf-bot-control.md).

## Rule statement characteristics
<a name="managed-rule-group-rule-statement-characteristics"></a>

**Not nestable** – You can't nest this statement type inside other statements, and you can't include it in a rule group. You can include it directly in a protection pack (web ACL). 

**(Optional) Scope-down statement** – This rule type takes an optional scope-down statement, to narrow the scope of the requests that the rule group evaluates. For more information, see [Using scope-down statements in AWS WAF](waf-rule-scope-down-statements.md).

**WCUs** – Set for the rule group at creation.

## Where to find this rule statement
<a name="managed-rule-group-rule-statement-where-to-find"></a>
+ **Console** – During the process of creating a protection pack (web ACL), on the **Add rules and rule groups** page, choose **Add managed rule groups**, and then find and select the rule group that you want to use.
+ **API** – [ManagedRuleGroupStatement](https://docs.aws.amazon.com/waf/latest/APIReference/API_ManagedRuleGroupStatement.html)

# Using rule group statements in AWS WAF
<a name="waf-rule-statement-type-rule-group"></a>

This section explains how rule group rule statements work.

The rule group rule statement adds a reference to your protection pack (web ACL) rules list to a rule group that you manage. You don't see this option under your rule statements on the console, but when you work with the JSON format of your protection pack (web ACL), any of your own rule groups that you've added show up under the protection pack (web ACL) rules as this type. For information about using your own rule groups, see [Managing your own rule groups](waf-user-created-rule-groups.md).

When you add a rule group to a protection pack (web ACL), you can override the actions of rules in the group to Count or to another rule action. For more information, see [Overriding rule group actions in AWS WAF](web-acl-rule-group-override-options.md).

## Rule statement characteristics
<a name="rule-group-rule-statement-characteristics"></a>

**Not nestable** – You can't nest this statement type inside other statements, and you can't include it in a rule group. You can include it directly in a protection pack (web ACL). 

**WCUs** – Set for the rule group at creation.

## Where to find this rule statement
<a name="rule-group-rule-statement-where-to-find"></a>
+ **Console** – During the process of creating a protection pack (web ACL), on the **Add rules and rule groups** page, choose **Add my own rules and rule groups**, **Rule group**, and then add the rule group that you want to use.
+ **API** – [RuleGroupReferenceStatement](https://docs.aws.amazon.com/waf/latest/APIReference/API_RuleGroupReferenceStatement.html)