Ongoing service disruptions
For the most recent update on ongoing service disruptions affecting the AWS Middle East (UAE) Region (ME-CENTRAL-1), refer to the AWS Health Dashboard. For information on AWS Service migration, see How do I migrate my services to another region?
How do I create complex custom JSON rules in AWS WAF?
I want to create complex custom JSON rules in AWS WAF.
Resolution
Create a complex custom rule
Complete the following steps:
- Open the AWS WAF console.
- In the navigation pane, choose Rule groups.
- Choose your rule group.
- Choose Manage rules and then choose Add rule.
- Choose Custom rule and then choose Next.
- Choose JSON, to open the rule JSON editor.
- Update the rule JSON editor with your custom rule.
- Choose Add rule.
Note: To create custom rules that use nested statements, you must use the JSON editor. Nested statements combine AND, OR, or NOT logic. For more information, see Using rule statement in AWS WAF.
Use the following examples as a reference to create your own custom rule logic.
Example 1
Use the following custom rule statement to allow a request when it originates from the United States - US and has the /wp-admin/ or /wp-login/ URI:
{ "Name": "test", "Priority": 100, "Statement": { "AndStatement": { "Statements": [ { "GeoMatchStatement": { "CountryCodes": [ "US" ] } }, { "OrStatement": { "Statements": [ { "ByteMatchStatement": { "SearchString": "/wp-admin/", "FieldToMatch": { "UriPath": {} }, "TextTransformations": [ { "Priority": 0, "Type": "NONE" } ], "PositionalConstraint": "CONTAINS" } }, { "ByteMatchStatement": { "SearchString": "/wp-login/", "FieldToMatch": { "UriPath": {} }, "TextTransformations": [ { "Priority": 0, "Type": "NONE" } ], "PositionalConstraint": "CONTAINS" } } ] } } ] } }, "Action": { "Allow": {} }, "VisibilityConfig": { "SampledRequestsEnabled": true, "CloudWatchMetricsEnabled": true, "MetricName": "test" } }
Rule logic: The request is (from US) AND URI is ( /a OR /b ) ).
Example 2
Use the following custom rule statement to block a request when it has XSS signatures in the body. The rule excludes the /test, /login, and /admin URIs from inspection:
{ "Name": "XSS_Block_Allow_Uploads", "Priority": 100, "Statement": { "AndStatement": { "Statements": [ { "XssMatchStatement": { "FieldToMatch": { "Body": {} }, "TextTransformations": [ { "Priority": 0, "Type": "NONE" } ] } }, { "NotStatement": { "Statement": { "OrStatement": { "Statements": [ { "ByteMatchStatement": { "SearchString": "/test", "FieldToMatch": { "UriPath": {} }, "TextTransformations": [ { "Priority": 0, "Type": "NONE" } ], "PositionalConstraint": "EXACTLY" } }, { "ByteMatchStatement": { "SearchString": "/admin", "FieldToMatch": { "UriPath": {} }, "TextTransformations": [ { "Priority": 0, "Type": "NONE" } ], "PositionalConstraint": "EXACTLY" } }, { "ByteMatchStatement": { "SearchString": "/login", "FieldToMatch": { "UriPath": {} }, "TextTransformations": [ { "Priority": 0, "Type": "NONE" } ], "PositionalConstraint": "EXACTLY" } } ] } } } } ] } }, "Action": { "Block": {} }, "VisibilityConfig": { "SampledRequestsEnabled": true, "CloudWatchMetricsEnabled": true, "MetricName": "XSS_Block_Allow_Uploads" } }
Rule logic: The request has (XSS signature in the body) AND URI is NOT ( /a OR /b, OR /c ).
Example 3
Use the following custom rule statement to block a request when it contains the internal custom label. Requests also can't have a specific combination for the host, IP address, and URI:
{ "Name": "Block_internal_unauthorized", "Priority": 100, "Statement": { "AndStatement": { "Statements": [ { "LabelMatchStatement": { "Scope": "LABEL", "Key": "internal" } }, { "NotStatement": { "Statement": { "AndStatement": { "Statements": [ { "ByteMatchStatement": { "FieldToMatch": { "UriPath": {} }, "PositionalConstraint": "EXACTLY", "SearchString": "/test", "TextTransformations": [{ "Type": "NONE", "Priority": 0 }] } }, { "IPSetReferenceStatement": { "ARN": "arn:aws:wafv2:us-east-1:555555555555:regional/ipset/internal_IPs/###-##-###" } }, { "ByteMatchStatement": { "FieldToMatch": { "SingleHeader": { "Name": "host" } }, "PositionalConstraint": "EXACTLY", "SearchString": "example.com", "TextTransformations": [{ "Type": "NONE", "Priority": 0 }] } } ] } } } } ] } }, "Action": { "Block": {} }, "VisibilityConfig": { "SampledRequestsEnabled": true, "CloudWatchMetricsEnabled": true, "MetricName": "Block_internal_unauthorized" } }
Rule logic: If the request (contains the label) AND not (URI and IP and host), then block.
- Tags
- AWS WAF
- Language
- English

This article was reviewed and updated on 2026-03-06
Relevant content
- asked 6 months ago
- asked 2 years ago
- Accepted Answerasked 3 years ago
- asked 10 months ago
AWS OFFICIALUpdated 2 years ago
AWS OFFICIALUpdated 6 months ago