Understanding Conditions

Describes how to understand and compose conditions for rules associated with WAF policies.

WAF uses a subset of the JMESPath language as a rule condition language. JMESPath is a query language for JSON (documentation: https://jmespath.org/specification.html) that you can use to write JMESPath expressions, where each expression takes a JSON document as an input (the input document) and returns a transformed or new JSON document (the output document).

In WAF, each rule accepts a JMESPath expression as the condition. HTTP requests or HTTP responses (depending on the type of rule) trigger WAF rules. When evaluating a rule, the WAF service evaluates the JMESPath expression (the condition) of the rule and provides an input JSON document, which includes the details of the HTTP request or HTTP response that triggered the evaluation. Then, the result of the evaluated JMESPath expression is used to determine whether to run the action specified in rule or not.

Thus, JMESPath expressions in WAF rules are used to inspect HTTP requests and HTTP responses to determine if the action in a WAF rule needs to be run or not. All JMESPath expressions used in WAF must return a boolean value, either true or false, where true means that the action of a rule is run and false means that the action is not run.

The following sections describe JMESPath functions specific to WAF:

Examples

URL path conditions:

# URL path equals
http.request.url.path == '/example/path'
        
# URL path does not equal
http.request.url.path != '/example/path'
        
# URL path contains
contains(http.request.url.path, 'example')
        
# URL path does not contain
!contains(http.request.url.path, 'example')
        
# URL path starts with
starts_with(http.request.url.path, '/example/path')
        
# URL path ends with
ends_with(http.request.url.path, '.png')
HTTP request method conditions
# HTTP request method is one of
contains(['GET', 'POST'], http.request.method)

HTTP request header conditions

# HTTP request header exists
contains(keys(http.request.headers), 'example-header')
        
# HTTP request header has specific value
http.request.headers."example-header"[0] == 'specific-value'
        
# One of the HTTP request headers with the same name has a specific value
contains(http.request.headers."example-header", 'specific-value')

Multiple conditions

# HTTP request method is GET and URL path starts with /example/path
http.request.method == 'GET' && starts_with(http.request.url.path, '/example/path')

# URL path starts with /example/path_one or /example/path_two
starts_with(http.request.url.path, '/example/path_one') || starts_with(http.request.url.path, '/example/path_two')

# HTTP request method is POST and URL is either /example/path_one or /example/path_two
http.request.method == 'POST' && (http.request.url.path == '/example/path_one' || http.request.url.path == '/example/path_two')

Supported JMESPath Subset

The WAF service does not support all JMESPath features, it supports a subset that can still be used to write complex conditions.

Restrictions on the full JMESPath feature set:

  • JMESPath conditions in WAF rules must be either:

    • A comparison that returns a boolean result.
    • Multiple such comparisons, combined with logical operators &&, ||.
  • A small subset of built-in JMESPath functions is supported:
    • contains

    • ends_with

    • keys

    • length

    • starts_with

A comparison is a JMESPath expression that compares two values. Either a JMESPath comparison operator (==, !=, >, >=, <, <=) or a comparison function (contains, ends_with, starts_with, all custom WAF functions) can be used to write a comparison expression.

The compared values can be one of:

Input JSON Document Structure

When evaluating JMESPath expressions, WAF provides an input JSON document, which includes the details of the HTTP request or HTTP response that triggered the evaluation. The input JSON document is always a JSON object.

Example

For an HTTP request with the following details:

  • Source IP address and port: 129.146.10.1:48152

  • Country code that the source IP address belongs to: US

  • ASN that the source IP address belongs to: 31898

  • Destination IP address and port: 205.147.88.0:80

  • Destination host: example.com

  • Protocol: HTTP/1.1

GET /test/path/img.jpg?param1=a&m2=b HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Cookie: cookie1=A; cookie2=B; cookie3=3C; cookie3=3D
Host: example.com
User-Agent: HTTPie/2.4.0

The following JSON input document is generated and passed to JMESPath expressions:

{
  "connection": {
    "source": {
      "address": "129.146.10.1",
      "port": 49152,
      "geo": {
        "countryCode": "US"
      },
      "routing": {
        "asn": 31898
      }
    },
    "destination": {
      "address": "205.147.88.0",
      "port": 80
    },
    "protocol": "http"
  },
  "http": {
    "request": {
      "host": "www.example.com",
      "method": "GET",
      "version": "1.1",
      "url": {
        "path": "/test/path/img.jpg",
        "query": "param1=a&param2=b",
        "queryParameters": {
          "param1": ["a"],
          "param2": ["b"]
        },
        "queryPrefix": "?"
      },
      "headers": {
        "accept": ["*/*"],
        "accept-encoding": ["gzip, deflate"],
        "connection": ["keep-alive"],
        "cookie": [
          "cookie1=A; cookie2=B; cookie3=3C; cookie3=3D"
        ],
        "host": ["www.example.com"],
        "user-agent": ["HTTPie/2.4.0"]
      },
      "cookies": {
        "cookie1": ["A"],
        "cookie2": ["B"],
        "cookie3": ["3C", "3D"]
      }
    }
  }
}

Reference

connection.source.address

Category

Value

Type

string

Description

A string containing the TCP source IP address. IPv6 addresses are represented in their canonical form, according to RFC 5952.

Internal only: For private connections coming through a service gateway, this contains the TCP source IP address of the original connection, in the source VCN.

Available in

requestAccessControl, requestRateLimiting, requestProtection, responseAccessControl, responseProtection

Example values

"10.0.0.1", "1.2.3.4"

connection.source.port

Category

Value

Type

number

Description

TCP source port

Available in

requestAccessControl, requestRateLimiting, requestProtection, responseAccessControl, responseProtection

Example values

49152

connection.source.geo.countryCode

Category

Value

Type

string | null

Description

ISO 3166-1 alpha-2 country code of the country which the source IP address belongs to. Can be null when the country is not known.

Available in

requestAccessControl, requestRateLimiting, requestProtection, responseAccessControl, responseProtection

Example values

"US"

connection.source.routing.asn

Category

Value

Type

number | null

Description

The ASN (autonomous system number) to which the source IP address belongs to. Can be null when the IP address is private.

Available in

requestAccessControl, requestRateLimiting, requestProtection, responseAccessControl, responseProtection

Example values

2122, 1278

connection.destination.address

Category

Value

Type

string

Description

A string containing the TCP destination IP address.

Available in

requestAccessControl, requestRateLimiting, requestProtection, responseAccessControl, responseProtection

Example values

"10.0.0.1"

connection.destination.port

Category

Value

Type

number

Description

TCP destination port

Available in

requestAccessControl, requestRateLimiting, requestProtection, responseAccessControl, responseProtection

Example values

80

connection.protocol

Category

Value

Type

string

Description

The protocol of the connection, either "http" or "https."

Available in

requestAccessControl, requestRateLimiting, requestProtection, responseAccessControl, responseProtection

Example values

"https"

http.request.host

Category

Value

Type

string

Description

The value of the HTTP request "Host" header. The "Host" request header specifies the host and port number of the server to which the request is being sent.

Available in

requestAccessControl, requestRateLimiting, requestProtection, responseAccessControl, responseProtection

Example values

"www.example.com", "api.example.com:8080"

http.request.method

Category

Value

Type

string

Description

The HTTP request method

Available in

requestAccessControl, requestRateLimiting, requestProtection, responseAccessControl, responseProtection

Example values

"GET", "POST"

http.request.version

Category

Value

Type

string

Description

HTTP protocol version

Available in

requestAccessControl, requestRateLimiting, requestProtection, responseAccessControl, responseProtection

Example values

"1.1", "2.0"

http.request.url.path

Category

Value

Type

string

Description

The absolute path part of the HTTP request target. Does not include the query part. Always starts with a "/".

Available in

requestAccessControl, requestRateLimiting, requestProtection, responseAccessControl, responseProtection

Example values

"/api/v1", "/index.html", "/"

http.request.url.query

Category

Value

Type

string

Description

The query parameters of the HTTP request target, without the prefix.

Available in

requestAccessControl, requestRateLimiting, requestProtection, responseAccessControl, responseProtection

Example values

"foo=bar&multi=1&multi=2", "multi=one&multi=two&multi=3&encoded=two%20words", ""

http.request.url.queryParameters

Category

Value

Type

object

Description

The query part of the HTTP request target, parsed into an object structure, where:

  • Key: the name of a query parameter.

  • Value: list of values with the "key" as their name.

Keys and values are unescaped according to URL escaping rules.

Available in

requestAccessControl, requestRateLimiting, requestProtection, responseAccessControl, responseProtection

Example values

Query part of the HTTP request target

Parsed object structure

?param1=a&param2=b&param3=c

{
  "param1": ["a"],
  "param2": ["b"],
  "param3": ["c"]
}

?multi=one&multi=two&multi=3&encoded+key=two%20words

{
  "multi": ["one","two", "3"],
  "encoded key": ["two words"]
}
http.request.url.queryParameters

Category

Value

Type

string

Description

The query prefix of the HTTP request target.

If a query string is present, it is always "?".

If no query string is present, it contains an empty string.

Available in

requestAccessControl, requestRateLimiting, requestProtection, responseAccessControl, responseProtection

Example values

"?", ""

http.request.headers

Category

Value

Type

object

Description

The HTTP request headers parsed into an object structure, where:

  • Key: lowercased name of the header.

  • Value: list of header values with the "key" as their name.

Available in

requestAccessControl, requestRateLimiting, requestProtection, responseAccessControl, responseProtection

Example values

Raw HTTP request headers

Parsed object structure

Accept: application/json, text/csv
Accept: */*
Accept-Encoding: gzip
Accept-Encoding: deflate
Connection: keep-alive
Content-Language: en, fr
Content-Type: application/json
Host: www.example.com
User-Agent: HTTPie/2.2.0
{
  "accept":           ["application/json, text/csv", "*/*"],
  "accept-encoding":  ["gzip", "deflate"],
  "connection":       ["keep-alive"],
  "content-language": ["en, fr"],
  "content-type":     ["application/json"],
  "host":             ["www.example.com"],
  "user-agent":       ["HTTPie/2.2.0"]
}
}
http.request.cookies

Category

Value

Type

object

Description

The HTTP cookies that were passed using the "Cookie" HTTP request header, parsed into an object structure, where:

  • Key: name of the cookie.

  • Value: list of cookie values with the "key" as their name.

Available in

requestAccessControl, requestRateLimiting, requestProtection, responseAccessControl, responseProtection

Example values

Value of the HTTP request header "Cookie"

Parsed object structure

cookie1=A; cookie2=B; cookie3=3C; cookie3=3D
{
  "cookie1": ["A"],
  "cookie2": ["B"],
  "cookie3": ["3C", "3D"]
}
http.response.code

Category

Value

Type

number

Description

HTTP response code

Available in

responseAccessControl, responseProtection

Example values

200

http.response.headers

Category

Value

Type

object

Description

The HTTP response headers parsed into an object structure, where:

  • Key: lowercased name of the header.

  • Value: list of header values with the "key" as their name.

Available in

responseAccessControl, responseProtection

Example values

Raw HTTP response headers

Parsed object structure

Cache-Control: no-cache
Cache-Control: must-revalidate
Connection: keep-alive
Content-Encoding: gzip
Content-Type: text/html;charset=UTF-8
{
  "cache-control":    ["no-cache", "must-revalidate"],
  "connection":       ["keep-alive"],
  "content-encoding": ["gzip"],
  "content-type":     ["text/html;charset=UTF-8"]
}

Case-Insensitive String Matching

In addition to string matching functions supported by default in JMESPath, WAF adds support for four functions that can match strings case-insensitively:

  • i_equals (case-insensitive variant of the == operator);
  • i_contains (case-insensitive variant of the contains function);
  • i_starts_with (case-insensitive variant of the starts_with function);
  • i_ends_with (case-insensitive variant of the ends_with function).

IP Address Matching

WAF adds support for multiple functions that can match an IP address against a list of CIDR ranges or WAF Network Address List resources:

  • address_in (matches an IP address against a list of CIDR ranges);

  • address_in_network_address_list (matches an IP address against a WAF Network Address List resource);

  • vcn_address_in_network_address_list (matches an IP address with a VCN ID against a WAF Network Address List resource).

Keys Function

The Keys function returns an array containing the keys of the provided object. Because JSON hashes are inherently unordered, the keys associated with the provided object "$obj" are inherently unordered.

array keys(object $obj)
Keys Function

Given

Expression

Result

{}

keys(@)

[]

{"foo": "baz", "bar": "bam"}

keys(@)

["foo", "bar"]

false

keys(@)

<error: invalid-type>

[b, a, c]

keys(@)

<error: invalid-type>

In WAF, keys() is only supported to check if http.request.headers, http.response.headers, http.request.url.query or http.request.cookies contains a specific key. See the following examples:

contains(keys(http.request.headers), 'x-forwarded-for')
contains(keys(http.request.url.query), 'my_test_param')
contains(keys(http.request.cookies), 'MyTestCookie')
contains(keys(http.response.headers), 'set-cookie')

Length Function

Returns the number of elements in the given array.

number length(array $subject)
Length Function
Given Expression Result

["a", "b", "c"]

length(@)

3

[]

length(@)

0

In WAF, length() only works with values of these variables: http.request.headers, http.response.headers, http.request.url.query or http.request.cookies. See the following examples:

length(http.request.headers."x-forwarded-for")
length(http.request.url.query."my_test_param")
length(http.request.cookies.MyTestCookie)
length(http.response.headers."set-cookie")