Understand and compose conditions for rules associated with WAF policies.
WAF uses the JMESPath language as a rule condition language. JMESPath is a query language for JSON (see https://jmespath.org/specification.htmlJMESPath selectors) 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 or not to run the action specified in the rule.
The return value of JMESPath conditions in WAF is converted to a boolean value. The following values are converted to "false":
Empty list: []
Empty object: {}
Empty string: ""
False boolean: false
Null value: null
All other values are converted to "true." True means that the action of a rule is run and false means that the action isn't run.
You can create a JMESPath condition with up to 1,024 characters.
Example
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')
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
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.
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).
i_equals
boolean i_equals(string $left, string $right)
Returns true if strings $left and $right are equal, when compared case-insensitively (both $left and $right strings are converted to lower case, only English letters are converted to lower case). Otherwise, returns false.
Given
Expression
Result
"string"
i_equals(@, 'string')
true
"string"
i_equals(@, 'STRING')
true
"string"
i_equals(@, 'sTrInG')
true
"STRING"
i_equals(@, 'string')
true
"string"
i_equals(@, 'other_string')
false
i_contains
boolean i_contains(array|string $subject, any $search)
Case-insensitive variant of the contains function.
If the provided $subject is a string, this function returns true if the string contains the provided $search argument, when compared case-insensitively (both $left and $right strings are converted to lower case, only English letters are converted to lower case). Otherwise, this function returns false.
If $subject is an array, this function returns true if at least one of the elements in the array is equal to the provided $search value, otherwise it returns false.
If $search is a string - comparison is done using the same logic as in i_equals() function: case-insensitive comparison (both the individual $subject array element and $search strings are converted to lower case, only English letters are converted to lower case).
If $search isn't a string - comparison is done using the standard == operator.
Returns true if the $subject starts with the $prefix, when compared case-insensitively (both $left and $right strings are converted to lower case, only English letters are converted to lower case). Otherwise, this function returns false.
Returns true if the $subject ends with the $suffix, when compared case-insensitively (both $left and $right strings are converted to lower case, only English letters are converted to lower case). Otherwise, this function returns false.
Given
Expression
Result
"foobarbaz"
i_ends_with(@, 'baz')
true
"foobarbaz"
i_ends_with(@, 'BAZ')
true
"foobarbaz"
i_ends_with(@, 'bAz')
true
"foobarbaz"
i_ends_with(@, 'bar')
false
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).
Returns true if the given $ip_address is contained in at least one of the provided Network Address Lists (a WAF resource containing a list of CIDR subnets). Otherwise, returns false.
$ip_address must be a string containing an IP address.
$nal_id arguments must be an array of strings, referencing WAF NetworkAddressList resources by ID. All referenced NetworkAddressLists must be of type: "ADDRESSES".
Returns true if the given $ip_address in VCN $vcn_id is contained in at least one of the provided Network Address Lists (a WAF resource containing a list of CIDR subnets). Otherwise, returns false.
$ip_address must be a string containing an IP address.
$vcn_id must be a string containing an OCID of a VCN.
$nal_ids must be an array of strings, referencing WAF NetworkAddressList resources by ID. All referenced NetworkAddressLists must be of type: "VCN_ADDRESSES".