Hi, I created a WAF WebACL with two rules.
The first rule named ${AWS::StackName}-WebACL-Rule1
blocks requests with User-Agent
header set to BotAgent
and returns the custom JSON response named Forbidden
with 403
HTTP status and response body { "message": "403 Forbidden" }
.
The second rule named ${AWS::StackName}-WebACL-Rule2
blocks requests that match AWSManagedRulesAnonymousIpList and is supposed to return the same 403
response as the first one.
Here's my WebACL configuration written in CloudFormation template:
Resources:
WebACL:
Type: AWS::WAFv2::WebACL
Properties:
Name:
Fn::Sub: ${AWS::StackName}-WebACL
Description: My CloudFront Web ACL
DefaultAction:
Allow: {}
VisibilityConfig:
SampledRequestsEnabled: true
CloudWatchMetricsEnabled: true
MetricName:
Fn::Sub: ${AWS::StackName}-WebACL
Scope: CLOUDFRONT
CustomResponseBodies:
Forbidden:
ContentType: APPLICATION_JSON
Content: '{ "message": "403 Forbidden" }'
Rules:
- Name:
Fn::Sub: ${AWS::StackName}-WebACL-Rule1
Priority: 0
Action:
Block:
CustomResponse:
ResponseCode: 403
CustomResponseBodyKey: Forbidden
VisibilityConfig:
SampledRequestsEnabled: true
CloudWatchMetricsEnabled: true
MetricName:
Fn::Sub: ${AWS::StackName}-WebACL-Rule1
Statement:
ByteMatchStatement:
FieldToMatch:
SingleHeader:
Name: User-Agent
PositionalConstraint: EXACTLY
SearchString: BotAgent
TextTransformations:
- Priority: 0
Type: NONE
- Name:
Fn::Sub: ${AWS::StackName}-WebACL-Rule2
Priority: 1
OverrideAction:
None: {}
VisibilityConfig:
SampledRequestsEnabled: true
CloudWatchMetricsEnabled: true
MetricName:
Fn::Sub: ${AWS::StackName}-WebACL-Rule2
Statement:
ManagedRuleGroupStatement:
Name: AWSManagedRulesAnonymousIpList
VendorName: AWS
RuleActionOverrides:
- Name: AnonymousIPList
ActionToUse:
Block:
CustomResponse:
ResponseCode: 403
CustomResponseBodyKey: Forbidden
- Name: HostingProviderIPList
ActionToUse:
Block:
CustomResponse:
ResponseCode: 403
CustomResponseBodyKey: Forbidden
I attached this WebACL to my CloudFront distribution and tested this WebACL with curl
command with NordVPN connection turned on.
$ curl -H "User-Agent: BotAgent" -isSL http://d32jyfppz17k8f.cloudfront.net/index.html
HTTP/1.1 403 Forbidden
Server: CloudFront
Date: Sat, 30 Sep 2023 07:22:34 GMT
Content-Length: 30
Connection: keep-alive
Content-Type: application/json
X-Cache: Error from cloudfront
Via: 1.1 7813c3b749fe8e3a44c4359da4183e70.cloudfront.net (CloudFront)
X-Amz-Cf-Pop: NRT57-P4
X-Amz-Cf-Id: 8u1RX4Fo2touzwz8Pw6kfq5YKA1y98EnFXcLcUh2Wadfq54xPqeGmA==
{ "message": "403 Forbidden" }
$ curl -isSL http://d32jyfppz17k8f.cloudfront.net/index.html
HTTP/1.1 403 Forbidden
Server: CloudFront
Date: Sat, 30 Sep 2023 07:22:59 GMT
Content-Type: text/html
Content-Length: 919
Connection: keep-alive
X-Cache: Error from cloudfront
Via: 1.1 12632bbc89afe55228d7f1ab9e5993a6.cloudfront.net (CloudFront)
X-Amz-Cf-Pop: NRT57-C3
X-Amz-Cf-Id: MbOyYmJpH8B601nrPeVY1eriKbaTxFC8d-6h5B-ZNH4vCHXORiLORg==
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML><HEAD><META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<TITLE>ERROR: The request could not be satisfied</TITLE>
</HEAD><BODY>
<H1>403 ERROR</H1>
<H2>The request could not be satisfied.</H2>
<HR noshade size="1px">
Request blocked.
We can't connect to the server for this app or website at this time. There might be too much traffic or a configuration error. Try again later, or contact the app or website owner.
<BR clear="all">
If you provide content to customers through CloudFront, you can find steps to troubleshoot and help prevent this error by reviewing the CloudFront documentation.
<BR clear="all">
<HR noshade size="1px">
<PRE>
Generated by cloudfront (CloudFront)
Request ID: MbOyYmJpH8B601nrPeVY1eriKbaTxFC8d-6h5B-ZNH4vCHXORiLORg==
</PRE>
<ADDRESS>
</ADDRESS>
</BODY></HTML>
The first curl
command returns the custom 403
response as expected since it matches the first WebACL rule. The second curl
command matches the second WebACL rule (since NordVPN is activated), but it doesn't return the custom response which I configured.
It is possible to override the AWS managed rule to Count
action if I changed the configuration as follows so that the requests from NordVPN connected environment will never be blocked.
CustomResponseBodyKey: Forbidden
- Name: HostingProviderIPList
ActionToUse:
- Block:
- CustomResponse:
- ResponseCode: 403
- CustomResponseBodyKey: Forbidden
+ Count: {}
How can I override an action from AWS managed rules to a Block
action with a custom response?
Thanks you for the very helpful post! I've successfully customized the block action with the following configurations.