Functions
The Cloudflare Firewall Rules language provides functions for manipulating and validating values in an expression:
- Transformation functions manipulate values extracted from an HTTP request.
- The HMAC Validation function tests the validity of an HMAC token. Use it to write expressions that target requests based on the presence of a valid HMAC token.
Transformation functions
The Cloudflare Firewall Rules language supports several functions that transform values extracted from HTTP requests. A common use case for transformation functions is the conversion of a string of characters to uppercase or lowercase, since by default, string evaluation is case sensitive.
For example, the lower()
function converts all uppercase characters in a string to lowercase.
In the expression below, thelower()
function transforms http.host
values to lowercase so that they match the target value "www.cloudflare.com"
:
lower(http.host) == "www.cloudflare.com"
Transformation functions that take arrays as an argument type require the [*]
index operator, which returns an array of values for each field.
The Cloudflare Firewall Rules language supports these transformation functions:
any(
Array
<Boolean>)Boolean
Returns
true
when the comparison operator in the argument returnstrue
for any of the values in the argument array. Returnsfalse
otherwise.- Example:
any(url_decode(http.request.body.form.values[*])[*] contains "an xss attack")
all(
Array
<Boolean>)Boolean
Returns
true
when the comparison operator in the argument returnstrue
for all of the values in the argument array. Returnsfalse
otherwise.- Example:
all(http.request.headers['content-type'][*] == "application/json")
concat(
String | Integer | bytes | Array elements
)String
Takes a comma-separated list of values. Concatenates the argument values into a single String.
- Example:
concat("String1"," ","String",2) == "String1 String2"
len(
String | bytes
)Integer
Returns the byte length of a String or Bytes field.
- Example:
len(http.host)
lower(
String
)String
Converts a string field to lowercase. Only uppercase ASCII bytes are converted. All other bytes are unaffected.
- Example:
lower(http.host) == "www.cloudflare.com"
remove_bytes(
bytes
)bytes
Returns a new byte array with all the occurrences of the given bytes removed.
- Example:
remove_bytes(http.host, "\x2e\x77") == "cloudflarecom"
upper(
String
)String
Converts a string field to uppercase. Only uppercase ASCII bytes are converted. All other bytes are unaffected.
- Example:
upper(http.host) == "WWW.CLOUDFLARE.COM"
url_decode(
String
)String
Decodes a URL formatted string, as in the following:
%20
and+
decode to space characters%E4%BD
decodes toä½
- Example:
any(url_decode(http.request.body.form.values[*])[*] contains "an xss attack")
HMAC validation
Overview
You can validate hash-based message authentication code (HMAC) tokens in a Firewall Rules expression by using the is_timed_hmac_valid_v0()
function, which has this signature:
is_timed_hmac_valid_v0( <String literal as Key>, <String field as MessageMAC>, <Integer literal as ttl>, <Integer as currentTimeStamp>, <Optional Integer literal as lengthOfSeperator, default: 0>, <Optional String literal as flags>) -> <Bool as result>
The is_timed_hmac_valid_v0()
function has these parameter definitions:
Key
String literal
- Specifies the secret cryptographic key for validating the HMAC.
MessageMAC
String
- Contains a concatenation of these HMAC elements: message, separator, timestamp, mac. For a definition and an example, see MessageMAC.
ttl
Integer literal
- Defines the time-to-live for the HMAC token, expressed in seconds. Determines how long the token is valid, relative to the time it was issued.
currentTimeStamp
Integer
- Represents the Unix timestamp when Cloudflare received the request, expressed in seconds. Pass the
http.request.timestamp.sec
field as an approximate value to this argument.
- Represents the Unix timestamp when Cloudflare received the request, expressed in seconds. Pass the
lengthOfSeparator
Integer literal
- Specifies the length of the separator between the timestamp and the message in the MessageMAC. Expressed in bytes, with a default value of 0.
flags
String literal
When you set this optional argument to
`s`
, the function expects the value of the base64-encoded mac in the MessageMAC argument to use the URL-safe character set with no padding.When you do not set the value of flags to
's'
, you must URL encode the base64 value for mac in the MessageMAC argument.
Usage
The is_timed_hmac_valid_v0()
function uses the supplied Key to generate a message authentication code (MAC) from the message and the timestamp regions of the MessageMAC. When the generated MAC matches the mac region of the MessageMAC and the token has not expired, the HMAC is valid and the function returns true
.
For example, the following expression matches requests to download.example.com
that do not include valid HMAC tokens:
http.host == "download.example.com"and not is_timed_hmac_valid_v0("mysecretkey", http.request.uri, 100000, http.request.timestamp.sec, 8)
To review examples of firewall rules that use HMAC validation, see Common use cases.
MessageMAC
A valid MessageMAC satisfies the regular expression
(.+)(.*)(\d{10})-(.{43,})
and is composed of these parentheses-delimited expressions:
Expression | Description | Example |
---|---|---|
(.+) | The message to validate | /download/cat.jpg |
(.*) | The separator between message and timestamp, commonly a parameter name | &verify= |
(\d{10}) | The 10-digit Unix timestamp when the MAC was issued, expressed in seconds | 1484063137 |
(.{43,}) | A base64-encoded version of the MAC. When you do not set the value of the urlSafe argument in the HMAC validation function to When the base64 MAC encoding is URL-safe, the value for maccontains 43 bytes. Otherwise, the value will be 44 bytes or more, because of URL encoding. | IaLGSmELTvlhfd0ItdN6PhhHTFhzx |
For details on generating a MessageMAC, see Implement token creation
HMAC validation examples
Simple case
Consider the case where the MessageMAC is contained entirely within a single field, as in this example URI path:
/download/cat.jpg?verify=1484063787-IaLGSmELTvlhfd0ItdN6PhhHTFhzx73EX8uy%2FcSDiIU%3D
Note how the URI maps to the elements of the MessageMac:
- message:
/download/cat.jpg
- separator:
?verify=
- timestamp:
1484063787
- mac:
IaLGSmELTvlhfd0ItdN6PhhHTFhzx73EX8uy%2FcSDiIU%3D
When the MessageMac is contained entirely within a single field such as http.request.uri
, using the validation function is straightforward. Simply pass the name of the field to the MessageMAC argument:
is_timed_hmac_valid_v0( "mysecretkey", http.request.uri, 100000, http.request.timestamp.sec, 8)
Concatenated MessageMAC argument
To compose a MessageMAC from more than one field, use the concat()
function.
This example constructs the MessageMAC by concatenating the request URI and two header fields:
is_timed_hmac_valid_v0( "mysecretkey", concat( http.request.uri, http.request.headers["timestamp"][0], "-", http.request.headers["mac"][0]), 100000, http.request.timestamp.sec, 0)
For more on concat()
usage, see Transformation functions.