API
WAAP
WAAP
Chosen image
Home/WAAP/WAAP rules/Advanced rules

Advanced rules

This feature is available for the Enterprise package.

Similarly to WAAP custom rules, you can create, edit, and manage advanced custom rules. These rules also contain “If/Then” statements, but they support more complex conditions created with the Common Expression Language (CEL) syntax.

Create advanced rules

Due to the highly technical aspect of the advanced rules functionality, the ability to create and manage these rules is currently only available through our API.

Check out the following guides for details on how to create advanced rules and their key components:

  • API docs: Learn how to construct and manage advanced rules.

  • Advanced rule objects and attributes: Get the list of all available objects you can use in rule expressions along with their respective attributes and types.

  • Source field objects: Check the available source field objects you can use in your expressions along with their respective attributes and types.

Advanced rule properties

The advanced rule object contains the following properties:

{
  "name": "string",
  "description": "",
  "enabled": true,
  "action": {
    "allow": {},
    "block": {
      "status_code": 403,
      "action_duration": "string"
    },
    "captcha": {},
    "handshake": {},
    "tag": {
      "tags": [
        "string"
      ]
    }
  },
  "source": "string",
  "phase": "access"
}

Each rule can contain only one action—block, allow, captcha, handshake, or tag. If you use multiple actions in a single rule, the API will return an error.

Field Description Values Details
name Rule name Can contain only ASCII letters, numbers, spaces, periods, and colons.
action The action to execute when a condition is true.
  • block: WAAP blocked the request.
  • allow: WAAP allowed the request.
  • captcha: WAAP presented the user with a CAPTCHA
  • handshake: WAAP. performed automatic browser validation.
  • tag: WAAP will generate a tag with no action.
On tag action, the tag field should be provided.

For the block action, setting up the status_code (integer) and action_duration (time in seconds) is optional. By default, the status is set to "status_code": 403, and duration equals to 0s.
source The condition part of the rule. Can reference namespace objects: request, whois, session, response, tags, user_agent, client_data, as well as use data and functions.

Supported Python operand syntax: and, or, in, not, ==, !=, >, <, etc.
Supported CEL operand syntax: ||, &&
Every string value should be enclosed in single quotation marks ' and not in double quotation marks ".
enabled Whether or not the rule is enabled. Boolean: true or false Default value: false
description A string to describe the purpose of the rule. Any string.
The character limit for the description field is 100 characters.
Default value: false
phase The request processing phase.
  • access: The advanced rule applies to the request phase (request headers and body available).
  • header_filter: The advanced rule applies to the response headers phase.
  • body_filter: The advanced rule applies to the response body phase.
Default value: access

Best practices

You can use our API documentation as a guide in constructing your own advanced rules. The following sections demonstrate a few examples of advanced rules created via our API using cURL.

Rate limiting

Block IPs that hit more than 200 requests per 5 seconds (changeable) when the following cookies don't exist. You can find more examples in our Rate limiting guide.

curl --request POST \
--url https://api.gcore.com/waap/v1/domains/{domain_id}/advanced-rules \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '{
    "action": {
        "block": {
            "status_code": 403
        }
    },
    "phase": "access",
    "name": "Block Scrappers",
    "description": "Block IPs that hit more than 200 requests per 5 seconds for any `events` paths",
    "enabled": false,
    "source": "request.rate_limit([], '.*events', 5, 200, [], [], '', 'ip') and not ('mb-web-ui' in request.headers['Cookie'] or 'mb-mobile-ios' in request.headers['Cookie'] or 'mobile-android' in request.headers['Cookie'] or 'mb-mobile-android' in request.headers['Cookie'] or 'session-token' in request.headers['Cookie']) and not request.headers['session']"
}'

Penalty rule

If a block action triggers, WAAP will tag matching requests with the penalty tag as long as the block action is active.

To ensure the blocking of specific sources, you must also check for the penalty tag by defining a separate rule that blocks requests with the penalty tag or by including the tag check as part of a rule's source condition.

Block all penalty requests

The following rule will block all requests with the penalty tag. This ensures block actions triggered by any rule will be enforced.

Creating a separate rule for the penalty tag is useful when you have exhausted the 5 tags limit in a single rule.

curl --request POST \
--url https://api.gcore.com/waap/v1/domains/{domain_id}/advanced-rules \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '{
    "action": {"block": {}},
    "phase": "access",
    "name": "Block Penalized Requests",
    "description": "Block requests that are detected with `penalty` tag",
    "enabled": false,
    "source": "tags.exists('penalty')"
}'

Block penalty requests of a specific rule

In this example, the check for the penalty tag is embedded in a specific rule, so creating a separate rule to block requests with the penalty tag is unnecessary.

curl --request POST \ 
--url https://api.gcore.com/waap/v1/domains/{domain_id}/advanced-rules \ 
--header 'accept: application/json' \ 
--header 'content-type: application/json' \ 
--data ' 
{
    "phase": "ACCESS",
    "action": {"block": {"statusCode": 403, "action_duration": "1h"}},
    "name": "Rate Limit IP",
    "description": "Block IPs that hit more than 30 requests per 1 minute",
    "enabled": True,
    "source": "request.rate_limit([], '.*', 60, 30, [], [], '', 'ip') or tags.exists('penalty')"
}
'

Validate a set of countries

Use JavaScript validation to challenge IPs that are coming from countries without certain cookies:

curl --request POST \
--url https://api.gcore.com/waap/v1/domains/{domain_id}/advanced-rules \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '{
    "action": {
        "handshake": {}
    },
    "phase": "access",
    "name": "Validate set of countries",
    "description": "Validate with JavaScript challenge IPs that are coming from the following countries",
    "enabled": false,
    "source": "whois.country in ['BR', 'VN', 'ID', 'TH', 'ME', 'XK', 'LK'] and not ('mb-web-ui' in request.headers['Cookie'] or 'mb-mobile-ios' in request.headers['Cookie'] or 'mobile-android' in request.headers['Cookie'] or 'mb-mobile-android' in request.headers['Cookie'])
}'

Add clients to allow list

curl --request POST \
--url https://api.gcore.com/waap/v1/domains/{domain_id}/advanced-rules \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '{
    "action": {
        "allow": {}
    },
    "name": "Whitelist known IPs",
    "enabled": false,
    "source": "request.ip == '117.20.32.5' or request.ip == '117.20.32.4' or request.ip_in_range('72.21.217.0', '72.21.217.255')"
}'

Tag and allow registered clients

Make sure that the tag value is enclosed in the double-quotes character ".

curl --request POST \
--url https://api.gcore.com/waap/v1/domains/{domain_id}/advanced-rules \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '{
    "name": "Tag registered clients",
    "description": "Detect and tag registered clients by cookie",
    "source": "'mb-mobile-android' in request.headers['Cookie']",
    "action": {
        "tag": {
            "tags": ["registered"]
        }
    }
}'
curl --request POST \
--url https://api.gcore.com/waap/v1/domains/{domain_id}/advanced-rules \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '{
    "name": "Allow registered clients",
    "description": "Allow registered clients",
    "source": "tags.exists('registered')",
    "action": {
        "allow": {}
    }
}'

Define login pages

curl --request POST \
--url https://api.gcore.com/waap/v1/domains/{domain_id}/advanced-rules \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '{
    "name": "Detect and Tag Login Pages",
    "source": "['url1/login','url2/signup'] in request.uri",
    "action": {
        "tag": {
            "tags": ["login page"]
        }
    }
}'

Review existing rules

After you create advanced rules, they will appear on the WAAP rules page in the Gcore Customer Portal. You can enable or disable the rules by clicking the relevant toggles.

Advanced rules section with a sample penaly fingerprint rule

Was this article helpful?