

**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). 

# Customized web requests and responses in AWS WAF
<a name="waf-custom-request-response"></a>

This section explains how to add custom web request and response handling behavior to your AWS WAF rule actions and default protection pack (web ACL) actions. Your custom settings apply whenever the action they're attached to applies. 

You can customize web requests and responses in the following ways: 
+ With Allow, Count, CAPTCHA, and Challenge actions, you can insert custom headers into the web request. When AWS WAF forwards the web request to the protected resource, the request contains the entire original request plus the custom headers that you've inserted. For the CAPTCHA and Challenge actions, AWS WAF only applies the customization if the request passes the CAPTCHA or challenge token inspection.
+ With Block actions, you can define a complete custom response, with response code, headers, and body. The protected resource responds to the request using the custom response provided by AWS WAF. Your custom response replaces the default Block action response of `403 (Forbidden)`.

**Action settings that you can customize**  
You can specify a custom request or response when you define the following action settings: 
+ Rule action. For information, see [Using rule actions in AWS WAF](waf-rule-action.md).
+ Default action for a protection pack (web ACL). For information, see [Setting the protection pack (web ACL) default action in AWS WAF](web-acl-default-action.md).

**Action settings that you cannot customize**  
You *cannot* specify custom request handling in the override action for a rule group that you use in a protection pack (web ACL). See [Using protection packs (web ACLs) with rules and rule groups in AWS WAF](web-acl-processing.md). Also see [Using managed rule group statements in AWS WAF](waf-rule-statement-type-managed-rule-group.md) and [Using rule group statements in AWS WAF](waf-rule-statement-type-rule-group.md).

**Temporary inconsistencies during updates**  
When you create or change a protection pack (web ACL) or other AWS WAF resources, the changes take a small amount of time to propagate to all areas where the resources are stored. The propagation time can be from a few seconds to a number of minutes. 

The following are examples of the temporary inconsistencies that you might notice during change propagation: 
+ After you create a protection pack (web ACL), if you try to associate it with a resource, you might get an exception indicating that the protection pack (web ACL) is unavailable. 
+ After you add a rule group to a protection pack (web ACL), the new rule group rules might be in effect in one area where the protection pack (web ACL) is used and not in another.
+ After you change a rule action setting, you might see the old action in some places and the new action in others. 
+ After you add an IP address to an IP set that is in use in a blocking rule, the new address might be blocked in one area while still allowed in another.

**Limits on your use of custom requests and responses**  
AWS WAF defines maximum settings for your use of custom requests and responses. For example, a maximum number of request headers per protection pack (web ACL) or rule group, and a maximum number of custom headers for a single custom response definition. For information, see [AWS WAF quotas](limits.md).

**Topics**
+ [

# Inserting custom request headers for non-blocking actions
](customizing-the-incoming-request.md)
+ [

# Sending custom responses for Block actions
](customizing-the-response-for-blocked-requests.md)
+ [

# Supported status codes for custom responses
](customizing-the-response-status-codes.md)

# Inserting custom request headers for non-blocking actions
<a name="customizing-the-incoming-request"></a>

This section explains how to instruct AWS WAF to insert custom headers into the original HTTP request when a rule action doesn't block the request. With this option, you only add to the request. You can't modify or replace any part of the original request. Use cases for custom header insertion include signaling a downstream application to process the request differently based on the inserted headers, and flagging the request for analysis.

**Important**  
This option applies to the rule actions Allow, Count, CAPTCHA, and Challenge and to protection pack (web ACL) default actions that are set to Allow. For more information about rule actions, see [Using rule actions in AWS WAF](waf-rule-action.md). For more information about default protection pack (web ACL) actions, see [Setting the protection pack (web ACL) default action in AWS WAF](web-acl-default-action.md).

## Considerations when using custom request header names
<a name="using-custom-request-header-names"></a>

**Prefixes added to request headers**  
AWS WAF prefixes all request headers that it inserts with `x-amzn-waf-`, to avoid confusion with the headers that are already in the request. For example, if you specify the header name `sample`, AWS WAF inserts the header `x-amzn-waf-sample`.

**Important**  
As a security practice, you can add a string match rule that blocks requests where the header already starts with `x-amzn-waf-`. This blocks requests from non-AWS WAF sources that mimic the `x-amzn-waf-` prefix string that is inserted by AWS WAF when processing custom request headers.

The following example shows a string match rule configured to block traffic where the `x-amzn-waf-` prefix was not inserted by AWS WAF:

```
    "Rules": [
        {
          "Name": "CustomHeader",
          "Priority": 0,
          "Statement": {
            "ByteMatchStatement": {
              "SearchString": " x-amzn-waf-",
              "FieldToMatch": {
                "Headers": {
                  "MatchPattern": {
                    "All": {}
                  },
                  "MatchScope": "KEY",
                  "OversizeHandling": "MATCH"
                }
              },
              "TextTransformations": [
                {
                  "Priority": 0,
                  "Type": "NONE"
                }
              ],
              "PositionalConstraint": "STARTS_WITH"
            }
          },
          "Action": {
            "Block": {}
          },
          "VisibilityConfig": {
            "SampledRequestsEnabled": true,
            "CloudWatchMetricsEnabled": true,
            "MetricName": "CustomHeader"
          }
        }
      ]
```

For information on using string match rules, see [String match rule statement](waf-rule-statement-type-string-match.md).

**Headers with the same name**  
If the request already has a header with the same name that AWS WAF is inserting, AWS WAF overwrites the header. So, if you define headers in multiple rules with identical names, the last rule to inspect the request and find a match would have its header added, and any previous rules would not. 

## Using custom headers with non-terminating rule actions
<a name="custom-request-header-non-terminating-rule-actions"></a>

Unlike the Allow action, the Count action doesn't stop AWS WAF from processing the web request using the rest of the rules in the protection pack (web ACL). Similarly, when CAPTCHA and Challenge determine that the request token is valid, these actions don't stop AWS WAF from processing the web request. So, if you insert custom headers using a rule with one of these actions, subsequent rules might also insert custom headers. For more information about rule action behavior, see [Using rule actions in AWS WAF](waf-rule-action.md).

For example, suppose you have the following rules, prioritized in the order shown: 

1. RuleA with a Count action and a customized header named `RuleAHeader`.

1. RuleB with an Allow action and a customized header named `RuleBHeader`.

If a request matches both RuleA and RuleB, AWS WAF inserts the headers `x-amzn-waf-RuleAHeader` and `x-amzn-waf-RuleBHeader`, and then forwards the request to the protected resource. 

AWS WAF inserts custom headers into a web request when it finishes inspecting the request. So if you use custom request handling with a rule that has the action set to Count, the custom headers that you add are not inspected by subsequent rules. 

## Custom request handling example
<a name="example-custom-request-handling"></a>

You define custom request handling for a rule's action or for a protection pack (web ACL)'s default action. The following listing shows the JSON for custom handling added to the default action for a protection pack (web ACL). 

```
{
 "Name": "SampleWebACL",
 "Scope": "REGIONAL",
 "DefaultAction": {
  "Allow": {
   "CustomRequestHandling": {
    "InsertHeaders": [
     {
      "Name": "fruit",
      "Value": "watermelon"
     },
     {
      "Name": "pie",
      "Value": "apple"
     }
    ]
   }
  }
 },
 "Description": "Sample protection pack (web ACL) with custom request handling configured for default action.",
 "Rules": [],
 "VisibilityConfig": {
  "SampledRequestsEnabled": true,
  "CloudWatchMetricsEnabled": true,
  "MetricName": "SampleWebACL"
 }
}
```

# Sending custom responses for Block actions
<a name="customizing-the-response-for-blocked-requests"></a>

This section explains how to instruct AWS WAF to send a custom HTTP response back to the client for rule actions or protection pack (web ACL) default actions that are set to Block. For more information about rule actions, see [Using rule actions in AWS WAF](waf-rule-action.md). For more information about default protection pack (web ACL) actions, see [Setting the protection pack (web ACL) default action in AWS WAF](web-acl-default-action.md).

When you define custom response handling for a Block action, you define the status code, headers, and response body. For a list of status codes that you can use with AWS WAF, see the section that follows, [Supported status codes for custom responses](customizing-the-response-status-codes.md). 

**Use cases**  
The use cases for custom responses include the following: 
+ Sending a non-default status code back to the client.
+ Sending custom response headers back to the client. You can specify any header name except for `content-type`.
+ Sending a static error page back to the client.
+ Redirecting the client to a different URL. To do this, you specify one of the `3xx` redirection status codes, like `301 (Moved Permanently)` or `302 (Found)`, and then specify a new header named `Location` with the new URL. 

**Interaction with responses that you define in your protected resource**  
Custom responses that you specify for the AWS WAF Block action take precedence over any response specifications that you define in your protected resource. 

The host service for the AWS resource that you protect with AWS WAF might permit custom response handling for web requests. Examples include the following: 
+ With Amazon CloudFront, you can customize the error page based on status code. For information, see [Generating custom error responses](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/GeneratingCustomErrorResponses.html) in the *Amazon CloudFront Developer Guide*. 
+ With Amazon API Gateway you can define the response and status code for your gateway. For information, see [Gateway responses in API Gateway](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-gatewayResponse-definition.html) in the *Amazon API Gateway Developer Guide*. 

You can't combine AWS WAF custom response settings with custom response settings in the protected AWS resource. The response specification for any individual web request comes either completely from AWS WAF or completely from the protected resource. 

For web requests that AWS WAF blocks, the following shows the order of precedence.

1. **AWS WAF custom response** – If the AWS WAF Block action has a custom response enabled, the protected resource sends the configured custom response back to the client. Any response settings that you might have defined in the protected resource itself have no effect. 

1. **Custom response defined in the protected resource** – Otherwise, if the protected resource has custom response settings specified, the protected resource uses those settings to respond to the client. 

1. **AWS WAF default Block response** – Otherwise, the protected resource responds to the client with the AWS WAF default Block response `403 (Forbidden)`. 

For web requests that AWS WAF allows, your configuration of the protected resource determines the response that it sends back to the client. You can't configure response settings in AWS WAF for allowed requests. The only customization that you can configure in AWS WAF for allowed requests is the insertion of custom headers into the original request, before forwarding the request to the protected resource. This option is described in the preceding section, [Inserting custom request headers for non-blocking actions](customizing-the-incoming-request.md). 

**Custom response headers**  
You can specify any header name except for `content-type`.

**Custom response bodies**  
You define the body of a custom response within the context of the protection pack (web ACL) or rule group where you want to use it. After you've defined a custom response body, you can use it by reference anywhere else in the protection pack (web ACL) or rule group where you created it. In the individual Block action settings, you reference the custom body that you want to use and you define the status code and header of the custom response. 

When you create a custom response in the console, you can choose from response bodies that you've already defined or you can create a new body. Outside of the console, you define your custom response bodies at the protection pack (web ACL) or rule group level, and then reference them from the action settings within the protection pack (web ACL) or rule group. This is shown in the example JSON in the following section. 

**Custom response example**  
The following example lists the JSON for a rule group with custom response settings. The custom response body is defined for the entire rule group, then referenced by key in the rule action.

```
{
 "ARN": "test_rulegroup_arn",
 "Capacity": 1,
 
 "CustomResponseBodies": {
  "CustomResponseBodyKey1": {
   "Content": "This is a plain text response body.",
   "ContentType": "TEXT_PLAIN"
  }
 },
 
 "Description": "This is a test rule group.",
 "Id": "test_rulegroup_id",
 "Name": "TestRuleGroup",
 
 "Rules": [
  {
   "Action": {
    "Block": {
     "CustomResponse": {
      "CustomResponseBodyKey": "CustomResponseBodyKey1",
      "ResponseCode": 404,
      "ResponseHeaders": [
       {
        "Name": "BlockActionHeader1Name",
        "Value": "BlockActionHeader1Value"
       }
      ]
     }
    }
   },
   "Name": "GeoMatchRule",
   "Priority": 1,
   "Statement": {
    "GeoMatchStatement": {
     "CountryCodes": [
      "US"
     ]
    }
   },
   "VisibilityConfig": {
    "CloudWatchMetricsEnabled": true,
    "MetricName": "TestRuleGroupReferenceMetric",
    "SampledRequestsEnabled": true
   }
  }
 ],
 "VisibilityConfig": {
  "CloudWatchMetricsEnabled": true,
  "MetricName": "TestRuleGroupMetric",
  "SampledRequestsEnabled": true
 }
}
```

# Supported status codes for custom responses
<a name="customizing-the-response-status-codes"></a>

This section lists the status codes that you can use in a custom response. For detailed information about HTTP status codes, see [Status Codes](https://www.rfc-editor.org/rfc/rfc9110.html#name-status-codes) by the Internet Engineering Task Force (IETF) and [List of HTTP status codes](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes) on Wikipedia.

The following are the HTTP status codes that AWS WAF supports for custom responses. 
+ `2xx Successful`
  + `200` – `OK`
  + `201` – `Created`
  + `202` – `Accepted` 
  + `204` – `No Content` 
  + `206` – `Partial Content`
+ `3xx Redirection `
  + `300` – `Multiple Choices`
  + `301` – `Moved Permanently`
  + `302` – `Found`
  + `303` –`See Other`
  + `304` – `Not Modified`
  + `307` – `Temporary Redirect`
  + `308` – `Permanent Redirect`
+ `4xx Client Error `
  + `400` – `Bad Request`
  + `401` – `Unauthorized`
  + `403` – `Forbidden`
  + `404` – `Not Found`
  + `405` – `Method Not Allowed`
  + `408` – `Request Timeout`
  + `409` – `Conflict`
  + `411` – `Length Required`
  + `412` – `Precondition Failed`
  + `413` – `Request Entity Too Large`
  + `414` – `Request-URI Too Long`
  + `415` – `Unsupported Media Type`
  + `416` – `Requested Range Not Satisfiable`
  + `421` – `Misdirected Request`
  + `429` – `Too Many Requests`
+ `5xx Server Error`
  + `500` – `Internal Server Error`
  + `501` – `Not Implemented`
  + `502` – `Bad Gateway`
  + `503` – `Service Unavailable`
  + `504` – `Gateway Timeout`
  + `505` – `HTTP Version Not Supported`