Skip to content

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 a complex custom rule

Complete the following steps:

  1. Open the AWS WAF console.
  2. In the navigation pane, choose Rule groups.
  3. Choose your rule group.
  4. Choose Manage rules and then choose Add rule.
  5. Choose Custom rule and then choose Next.
  6. Choose JSON, to open the rule JSON editor.
  7. Update the rule JSON editor with your custom rule.
  8. 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.

AWS OFFICIALUpdated 7 days ago