Can I write advanced filters in Event Logs with AND/OR, NOT, regex and JSONata expressions?
Short answer
Yes. The Log Filter condition builder in the server filter supports all of them. AND/OR: conditions are set up in groups; within a group a condition is added with Add Condition, and a new group with the + icon next to the first group (at most 10 groups), and the connection within a group (default and) and the connection between groups (default or) are selected with separate switches. NOT: there is no separate "not" switch; the negative of every operator is its own option (Not equal to, None of, Includes None of, Does not contain, Does not start with, Does not end with, Does not match regex). Regex: Matches Regex and Does not match regex take a JavaScript regular expression. Text comparisons and regex do not observe the case distinction. On numeric fields there are the Greater than and Less than variants, on the Client IP field IP/cidr match, and on every field except the vService field in Global WAF Event Log, Exists. JSONata: ⚡ Expression (JSONata) is selected from the field list and the expression is written (e.g. "veryHigh" in $severity()). The filter is applied with Save & Get Logs and runs on the server; the same builder is also used in the Report Filter field in WAF Report.
Syntax
| Requirement | Equivalent |
|---|---|
| AND / OR | and / or switch within a group and between groups |
| NOT | The negative option of the operator |
| Equality and list | Equals to / Not equal to · Any of / None of |
| Text | Contains, Starts with, Ends with and their negatives |
| Regex | Matches Regex / Does not match regex |
| Number (WAF score, ASN) | Greater than, Greater than or Equal to, Less than, Less than or Equal to |
| IP block (Client IP) | IP/cidr match |
| Classification (Taxonomy group, Severity) | Includes Any of / Includes None of |
| Existence | Exists |
| Free expression | ⚡ Expression (JSONata) |
The type of the field determines which operators are offered; e.g. Country offers only the equality, list and Exists operators, and yes/no fields such as Monitor Only and Blacklist offer the Equals to and Exists operators.
Solution
Condition Group with Log Filter
- How it worksLog Filter is applied on the server side to every record that is read; the reading continues backwards until as many matching records as Line Limit are found or the date range ends. In filters that contain attack-based fields (Taxonomy group, Severity) or a JSONata expression, the attacks that do not match the condition are removed from the record.
- Where it is openedEvent Logs or Global WAF Event Log → the server filter tab at the beginning of the filter strip → Log Filter
- Requirement WAF permission
- vService type HTTP
Step-by-Step Configuration
Example: Requests that come from Russia or China and are blocked in the SQL Injection category.
On the Event Logs screen, the fixed tab at the beginning of the filter strip is clicked (server filter).
The Add Advanced Filter button on the Log Filter row is clicked; the first group and the first condition open.
Network · Country is selected as the field, Any of as the operator, and two countries as the value.
Add Condition below the group is clicked; in the new condition, Taxonomy · Category → Includes Any of → SQL Injection is selected. The connection switch within the group is left in the and position.
WAF · Action → Equals to → Blocking is added with Add Condition.
If another set of conditions is to be added with or, the green + icon next to the first group is clicked; the switch between groups comes as or by default and is set to and if needed.
Save & Get Logs is clicked; the filter is stored per user.
Regex example: Request · Path → Matches Regex → the value ^/api/v[0-9]+/ catches the paths /api/v1/users and /API/V2/x, and does not catch the path /apiv1/. The pattern is compiled as a JavaScript regular expression; when an invalid pattern is saved, the filter cannot be run and an error is returned.
JSONata example: ⚡ Expression (JSONata) is selected from the field list and a JSONata expression is written. The expression can use the following built-in functions: $categories(), $cwes(), $mitres(), $capecs(), $owaspWebs(), $owaspApis(), $targets(), $attackIds(), $scopes(), $severity(), $action(), $learned(), $blacklisted().
"veryHigh" in $severity()
$action() = "blocking" and "sqlInjection" in $categories()The first expression selects the records that have at least one Very High attack, and the second the records that are blocked and carry an attack in the SQL Injection category. The $action() value is blocking, monitor or teacher; the $severity() values are blacklist, structural, veryHigh, high, medium, low, veryLow; $categories() returns the category IDs (e.g. sqlInjection, xss). A filter that contains a JSONata expression is evaluated separately for every attack in the record: the attacks that match the expression stay in the record, and those that do not match are removed from the record. For this reason, inside the expression attacks carries a single attack each time; an expression based on the number of attacks (such as $count(attacks) > 2) does not select the expected records. Request-level conditions such as the score, IP and path are set up in the same group with field conditions such as WAF Score → Greater than.
Verification
The title of the server filter tab shows the number of defined conditions; the Action icon of the records in the list and the attacks in the preview are compared with the condition.
Last 7 day(s) - 3 advanced filter(s)Common Misconceptions
- "Regex is case-sensitive." Text comparisons and regex in Log Filter do not observe the case distinction.
- "There is a separate switch for NOT." Negation is set up with the negative option of the operator.
- "The number in the tab title is the number of groups." The number is the total number of conditions in the groups.
- "Selections on the filter strip are added to Log Filter." The strip only filters the records that have been pulled; Log Filter determines which records are pulled (How do I filter logs by fields such as IP, country, ASN, path, signature, category, OWASP and CWE?).
- "Request Unique ID is a field in the advanced filter." For the ID, there is a separate Request Unique ID box in the server filter (How do I find a specific request by its Request Unique ID?).
How it is done in the documentation
