I trying to implement WAF protection at AWS and using WAS WAF v2.
What I need:
- Add custom responses when request is blocked
- Exclude payload body size check (
SizeRestrictions_BODY) fromAWS-AWSManagedRulesCommonRuleSetrule - Block request if any other check is positive
What I tried:
Here is JSON of my example WEB ACL:
{
"Name": "example",
"Id": "uuiduuid-uuid-uuid-uuiduuid",
"ARN": "arn:aws:wafv2:ap-northeast-1:0123456789:regional/webacl/example/uuiduuid-uuid-uuid-uuiduuid",
"DefaultAction": {
"Allow": {}
},
"Description": "WAF example",
"Rules": [
{
"Name": "AWS-AWSManagedRulesAmazonIpReputationList",
"Priority": 0,
"Statement": {
"ManagedRuleGroupStatement": {
"VendorName": "AWS",
"Name": "AWSManagedRulesAmazonIpReputationList"
}
},
"OverrideAction": {
"Count": {}
},
"VisibilityConfig": {
"SampledRequestsEnabled": false,
"CloudWatchMetricsEnabled": false,
"MetricName": "AWS-AWSManagedRulesAmazonIpReputationList"
}
},
{
"Name": "AWS-AWSManagedRulesCommonRuleSet",
"Priority": 1,
"Statement": {
"ManagedRuleGroupStatement": {
"VendorName": "AWS",
"Name": "AWSManagedRulesCommonRuleSet",
"ExcludedRules": [
{
"Name": "SizeRestrictions_BODY"
}
]
}
},
"OverrideAction": {
"Count": {}
},
"VisibilityConfig": {
"SampledRequestsEnabled": false,
"CloudWatchMetricsEnabled": false,
"MetricName": "AWS-AWSManagedRulesCommonRuleSet"
}
},
{
"Name": "BlockLabeledRequests",
"Priority": 2,
"Statement": {
"OrStatement": {
"Statements": [
{
"LabelMatchStatement": {
"Scope": "NAMESPACE",
"Key": "awswaf:managed:aws:"
}
},
{
"NotStatement": {
"Statement": {
"LabelMatchStatement": {
"Scope": "LABEL",
"Key": "awswaf:managed:aws:core-rule-set:SizeRestrictions_Body"
}
}
}
}
]
}
},
"Action": {
"Block": {
"CustomResponse": {
"ResponseCode": 499,
"CustomResponseBodyKey": "custom-response-body",
"ResponseHeaders": [
{
"Name": "x-custom-header",
"Value": "hello-world"
}
]
}
}
},
"VisibilityConfig": {
"SampledRequestsEnabled": false,
"CloudWatchMetricsEnabled": false,
"MetricName": "BlockLabeledRequests"
}
}
],
"VisibilityConfig": {
"SampledRequestsEnabled": false,
"CloudWatchMetricsEnabled": true,
"MetricName": "waf-example"
},
"Capacity": 727,
"ManagedByFirewallManager": false,
"LabelNamespace": "awswaf:0123456789:webacl:example:",
"CustomResponseBodies": {
"custom-response-body": {
"ContentType": "APPLICATION_JSON",
"Content": "{\n \"error\": \"oops, something wrong\"\n}"
}
}
}
What is happening here:
- Request go through
AWSManagedRulesAmazonIpReputationListrule. If this check is not passed (positive)awswaf:managed:aws:rule-set-name:rule-namelabel will be added. - Because of default action overridden to
Countrequest go to next rule in any way. (Why I can't block bad request immediately? Because default block action of the rule returning standard response, but I have to customize it. And that is not possible to overrideBlockresponse. OnlyCountmay be overridden. And that is stupid limitation N1.) - Request go through
AWS-AWSManagedRulesCommonRuleSetrule and even ifSizeRestrictions_BODY's action overridden toCount, the rule still adding own labelawswaf:managed:aws:core-rule-set:SizeRestrictions_Bodyto request but not blocks it (It is not possible to disable rule at all, at leastCountshould be triggered. Stupid limitation N2.) - Rule set action overridden to
Count, so request goes to final rule - Final rule
BlockLabeledRequestschecks if any label starting fromawswaf:managed:aws:exists in request and blocks it if YES. ButSizeRestrictions_Bodyadding own label starting fromawswaf:managed:aws:and that makes impossible to useawswaf:managed:aws:existence check. Because of it I set two conditions: Request will be blocked if has label starting fromawswaf:managed:aws:or doesn't have labelawswaf:managed:aws:core-rule-set:SizeRestrictions_Body. In most cases it working correct, but if we add to request big sized payloadSizeRestrictions_Bodywill be triggered and request will be passed even if we have another rules triggered, and that is a security hole. WAF if statements logic is pretty dumb and only one possible way to excludeSizeRestrictions_Bodyis to check allawswaf:managed:aws:rule-set-name:rule-nameone by one withif andstatement and excludeSizeRestrictions_Bodyfrom it. But it is inconvenient because number of rules is pretty big. (stupid limitation N3.)
QUESTION: So is here any way to set thing What I need by any another logic? Or just exclude only awswaf:managed:aws:core-rule-set:SizeRestrictions_Body label check but use wildcard label check awswaf:managed:aws: at same time? Or may be here is some way to force remove awswaf:managed:aws:core-rule-set:SizeRestrictions_Body label from request before label checking?
AWS WAF limitations making it pretty useless