How do I create complex custom JSON rules in AWS WAF?

4 minute read
1

I want to create complex custom JSON rules in AWS WAF.

Resolution

Create complex custom rules in the Rule JSON editor under Web ACLs and Rule groups in the AWS WAF console. Access the rule through its rule group or the web access control list (web ACL) where it's defined.

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 Rule statement basics.

To create rule statements, use the Rule visual editor in the AWS WAF console. Then, choose Rule JSON editor to view the JSON statements and make the necessary changes in the JSON editor.

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:xxxxxxxxxxxx:regional/ipset/internal_IPs/xxx-xx-xxx"
                    }
                  },
                  {
                    "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.

AWS OFFICIAL
AWS OFFICIALUpdated 3 months ago