WAF Exceptions
Web Application Firewall (WAF) Exceptions are configurations that explicitly allow certain request patterns to bypass blocking, overriding the standard WAF security rules that would otherwise identify these requests as potentially malicious. They operate at a high level, analyzing specific components of HTTP requests, such as parameters (ARGS), request body contents (BODY), or the URL path (URL). Each exception is defined with a unique identifier, a match string, and an application zone, ensuring that the security filter remains effective while minimizing blocks on requests containing characteristics considered necessary or legitimate by the user, thus reducing false positives.
Prerequisites
To instantiate Custom Allowed Rules in a WAF Rule Set, you must have an Firewall configuration with the Web Application Firewall module activated.
WAF Tuning
Azion’s WAF Tuning feature is an analytical tool that allows you to identify blocks triggered by WAF rules based on traffic logs, enabling you to detect potential attacks and determine which cases can be allowed if they represent expected or accepted behavior. This resource allows users to adjust the WAF’s precision to avoid false positives or permit legitimate traffic.
With WAF Tuning, you can analyze traffic distributed across network lists, IPs, and countries that correspond to your configured WAF rule sets.
For more information on how WAF tuning works in practice, check our guide on how to configure it.
When is it appropriate to use them?
WAF Custom Allowed Rules should be used with caution and only in specific situations, such as:
- Scenarios where false positives are impacting legitimate traffic, in the form of requests being responded to users with HTTP Status 400 or the response configured by the WAF.
- The need to allow requests from trusted partners or systems that use unconventional patterns.
- During testing and validation of new features in controlled environments.
Best practices for using WAF Custom Allowed Rules
Companies can maintain an appropriate balance between security and functionality, minimizing potential risks associated with the incorrect use of WAF Custom Allowed Rules.
- Minimization and specificity: only allow what is necessary and be specific. Instead of broadly releasing many WAF rules, restrict them to the minimum viable and apply Allowed Rules only to the exact parts of the requests that are required.
- Review and audit: regularly evaluate WAF Custom Allowed Rules to ensure they are still necessary and appropriate, removing unnecessary or outdated entries. The WAF Tuning feature exists to assist in this process.
- Testing and monitoring: after implementing a WAF Custom Allowed Rule, perform rigorous testing to ensure no vulnerabilities are introduced. Monitor logs to identify anomalous behaviors or unauthorized access using Real-Time Events and Data Stream.
- Environment segregation: whenever possible, use different sets of WAF Custom Allowed Rules for development, testing, and production environments, adjusting permissions as needed for each context.
- Documentation: maintain clear documentation about the rules created and the reasoning behind each one to facilitate future reviews and audits.
Security risks associated with the implementation of Web Application Firewall (WAF) Custom Allowed Rules
The incorrect use of WAF Custom Allowed Rules can expose web applications to significant risks. If too permissive or poorly configured, they can create security gaps that allow malicious traffic to enter, rendering security measures ineffective or reducing their impact. For example, by broadly allowing certain patterns or zones without careful analysis, malicious users can exploit these exceptions to inject code or execute brute force attacks.
Practical example of a WAF Custom Allowed Rule in action
Scenario
You have a web application protected by Azion’s Web Application Firewall (WAF). One of the WAF’s default rules is blocking requests that contain special characters in the query string parameter, potentially indicating an SQL Injection attempt. However, you notice that a legitimate API in your application uses these special characters as part of its normal operation.
Problem
- The WAF is blocking legitimate API requests, generating false positives.
- Legitimate traffic is interrupted, negatively impacting the user experience.
Solution with WAF Custom Allowed Rule
- Problem identification
- In WAF Tuning, you analyze blocked traffic logs and identify that legitimate requests are being blocked by the rule with the Rule ID corresponding to SQL Injection.
- Creating an Allowed Rule to allow legitimate requests that meet specific criteria, such as the API path or query parameter.
- Configuring the Allowed Rule:
- Go to the Allowed Rules tab in the WAF rule set.
- Click + Allowed Rule and configure the following parameters:
- Rule ID: choose the rule that’s generating the false positive (for example, “SQL Injection”).
- Path: specify the API path that should be allowed (for example,
/api/v1/data). - Match Zone: set to check only the query string.
- Regex: enable if the allowed values contain specific patterns (for example,
^[a-zA-Z0-9]+$). - Status: enable the rule.
- Save the rule and test the application.
- Now, legitimate requests to
/api/v1/datawith special characters in the query string will be allowed, while other requests that violate the rule will continue to be blocked.
Result
The WAF continues to protect your application against SQL Injection attacks while now allowing legitimate traffic to the API. The user experience is restored, and application security is maintained.
Practical example of an Allowed Rule
Consider that the API receives requests like this:
GET /api/v1/data?filter=name%20LIKE%20%27%test%27This request would be blocked by the SQL Injection rule due to the use of characters such as % and '. With the configured Allowed Rule, the WAF permits this request because it meets the defined criteria (path /api/v1/data and specific query string).
Benefits
- Customization: adjust the WAF to meet the specific needs of your application.
- Reduced false positives: allow legitimate traffic without compromising security.
- Security maintenance: requests that don’t meet the criteria of the Allowed Rule continue to be blocked.
WAF internal rules
Your WAF Custom Allowed Rules can be based on actual requests that were marked by WAF as possible threats. You can also allow a custom rule in case of tests and false positives.
When creating custom allowed rules for a WAF configuration, it’s necessary to choose between the available internal rules for its composition.
See the list of all available internal rules below:
| Rule ID | Description |
|---|---|
| 1 | Weird request, unable to parse. |
| 2 | Request larger than 128 kilobytes, stored on disk, and not parsed. |
| 10 | Invalid HEX encoding (null bytes). |
| 11 | Missing or unknown Content-Type header in a POST (this rule applies only to Request Body match zone). |
| 12 | Invalid formatted URL. |
| 13 | Invalid POST format. Note: requests that fall under rule 13 will be blocked in some cases, even if the WAF is operating in learning mode. Read the Rules Engine for Firewall documentation for the definition of learning/blocking modes. Read this guide how to check your WAF mode. |
| 14 | Invalid POST boundary. |
| 15 | Invalid JSON format. |
| 16 | POST with no body. |
| 17 | Possible SQL Injection attack: validation with libinjection_sql. |
| 18 | Possible XSS attack: validation with libinjection_xss. |
| 1000 | Possible SQL Injection attack: SQL keywords found in Body, Path, Query String, or Cookies. |
| 1001 | Possible SQL Injection or XSS attack: double quote " found in Body, Path, Query String or Cookies. |
| 1002 | Possible SQL Injection attack: possible hex encoding 0x found in Body, Path, Query String or Cookies. |
| 1003 | Possible SQL Injection attack: MySQL comment /* found in Body, Path, Query String or Cookies. |
| 1004 | Possible SQL Injection attack: MySQL comment */ found in Body, Path, Query String or Cookies. |
| 1005 | Possible SQL Injection attack: MySQL keyword | found in Body, Path, Query String or Cookies. |
| 1006 | Possible SQL Injection attack: MySQL keyword && found in Body, Path, Query String or Cookies. |
| 1007 | Possible SQL Injection attack: MySQL comment -- found in Body, Path, Query String or Cookies. |
| 1008 | Possible SQL Injection or XSS attack: semicolon ; found in Body, Path or Query String. |
| 1009 | Possible SQL Injection attack: equal sign = found in Body or Query String. |
| 1010 | Possible SQL Injection or XSS attack: open parenthesis ( found in Body, Path, Query String or Cookies. |
| 1011 | Possible SQL Injection or XSS attack: close parenthesis ) found in Body, Path, Query String or Cookies. |
| 1013 | Possible SQL Injection or XSS attack: apostrophe ' found in Body, Path, Query String or Cookies. |
| 1015 | Possible SQL Injection attack: comma , found in Body, Path, Query String or Cookies. |
| 1016 | Possible SQL Injection attack: MySQL comment # found in Body, Path, Query String or Cookies. |
| 1017 | Possible SQL Injection attack: double at sign @@ found in Body, Path, Query String or Cookies. |
| 1100 | Possible RFI attack: scheme http:// found in Body, Query String or Cookies. |
| 1101 | Possible RFI attack: scheme https:// found in Body, Query String or Cookies. |
| 1102 | Possible RFI attack: scheme ftp:// found in Body, Query String or Cookies. |
| 1103 | Possible RFI attack: scheme php:// found in Body, Query String or Cookies. |
| 1104 | Possible RFI attack: scheme sftp:// found in Body, Query String or Cookies. |
| 1105 | Possible RFI attack: scheme zlib:// found in Body, Query String or Cookies. |
| 1106 | Possible RFI attack: scheme data:// found in Body, Query String or Cookies. |
| 1107 | Possible RFI attack: scheme glob:// found in Body, Query String or Cookies. |
| 1108 | Possible RFI attack: scheme phar:// found in Body, Query String or Cookies. |
| 1109 | Possible RFI attack: scheme file:// found in Body, Query String or Cookies. |
| 1110 | Possible RFI attack: scheme gopher:// found in Body, Query String or Cookies. |
| 1200 | Possible Directory Traversal attack: double dot .. found in Body, Path, Query String or Cookies. |
| 1202 | Possible Directory Traversal attack: obvious probe /etc/passwd found in Body, Path, Query String or Cookies. |
| 1203 | Possible Directory Traversal attack: obvious Windows path c:\\ found in Body, Path, Query String or Cookies. |
| 1204 | Possible Directory Traversal attack: obvious probe cmd.exe found in Body, Path, Query String or Cookies. |
| 1205 | Possible Directory Traversal attack: backslash \ found in Body, Path, Query String or Cookies. |
| 1207 | Possible Directory Traversal attack: obvious probe /..;/) found in Query String or Path. |
| 1208 | Possible Directory Traversal attack: obvious probe /.;/) found in Query String or Path. |
| 1209 | Possible Directory Traversal attack: obvious probe /.%.2e/ found in Query String or Path. |
| 1210 | Possible Directory Traversal attack: obvious probe /%2e./ found in found in Query String or Path. |
| 1302 | Possible XSS attack: HTML open tag < found in Body, Path, Query String or Cookies. |
| 1303 | Possible XSS attack: HTML close tag > found in Body, Path, Query String or Cookies. |
| 1310 | Possible XSS attack: open square bracket [ found in Body, Path, Query String or Cookies. |
| 1311 | Possible XSS attack: close square bracket ] found in Body, Path, Query String or Cookies. |
| 1312 | Possible XSS attack: tilde character ~ found in Body, Path, Query String, or Cookies. |
| 1314 | Possible XSS attack: ` (backtick) found in Body, Path, Query String, or Cookies. |
Managing Exceptions via API
You can manage WAF Exceptions programmatically using the Azion API. This enables you to automate the creation, update, and deletion of exceptions, integrate WAF calibration into CI/CD pipelines, and build custom tools for managing your security posture.
API endpoints
The Exceptions API provides the following operations:
| Operation | Endpoint | Description |
|---|---|---|
| List | GET /v4/edge_firewall/wafs/{waf_id}/exceptions | List all exceptions for a WAF Rule Set |
| Create | POST /v4/edge_firewall/wafs/{waf_id}/exceptions | Create a new exception |
| Retrieve | GET /v4/edge_firewall/wafs/{waf_id}/exceptions/{exception_id} | Get details of a specific exception |
| Update | PUT /v4/edge_firewall/wafs/{waf_id}/exceptions/{exception_id} | Update an existing exception |
| Partial update | PATCH /v4/edge_firewall/wafs/{waf_id}/exceptions/{exception_id} | Update specific fields of an exception |
| Delete | DELETE /v4/edge_firewall/wafs/{waf_id}/exceptions/{exception_id} | Delete an exception |
For complete API specifications, refer to the Azion API reference.
Listing exceptions
To retrieve all exceptions configured for a WAF Rule Set:
curl --request GET \ --url https://api.azion.com/v4/edge_firewall/wafs/{waf_id}/exceptions \ --header 'Accept: application/json' \ --header 'Authorization: Token [TOKEN VALUE]'Response example:
{ "count": 2, "results": [ { "id": 1234, "rule_id": 1000, "reason": "Allow legitimate API traffic", "match_zone": "query_string", "match_pattern": "^[a-zA-Z0-9]+$", "path": "/api/v1/data", "active": true }, { "id": 5678, "rule_id": 1302, "reason": "Allow HTML in specific endpoint", "match_zone": "body", "match_pattern": "<script>", "path": "/api/v1/render", "active": true } ]}Creating an exception
To create a new exception for a WAF Rule Set:
curl --request POST \ --url https://api.azion.com/v4/edge_firewall/wafs/{waf_id}/exceptions \ --header 'Accept: application/json' \ --header 'Authorization: Token [TOKEN VALUE]' \ --header 'Content-Type: application/json' \ --data '{ "rule_id": 1000, "reason": "Allow legitimate API traffic with SQL-like patterns", "match_zone": "query_string", "match_pattern": "^[a-zA-Z0-9\\s]+$", "path": "/api/v1/search", "active": true }'Retrieving a specific exception
To get details of a specific exception:
curl --request GET \ --url https://api.azion.com/v4/edge_firewall/wafs/{waf_id}/exceptions/{exception_id} \ --header 'Accept: application/json' \ --header 'Authorization: Token [TOKEN VALUE]'Updating an exception
To update all fields of an existing exception:
curl --request PUT \ --url https://api.azion.com/v4/edge_firewall/wafs/{waf_id}/exceptions/{exception_id} \ --header 'Accept: application/json' \ --header 'Authorization: Token [TOKEN VALUE]' \ --header 'Content-Type: application/json' \ --data '{ "rule_id": 1000, "reason": "Updated reason for the exception", "match_zone": "query_string", "match_pattern": "^[a-zA-Z0-9\\s\\-]+$", "path": "/api/v1/search", "active": true }'Partially updating an exception
To update specific fields without modifying the entire exception:
curl --request PATCH \ --url https://api.azion.com/v4/edge_firewall/wafs/{waf_id}/exceptions/{exception_id} \ --header 'Accept: application/json' \ --header 'Authorization: Token [TOKEN VALUE]' \ --header 'Content-Type: application/json' \ --data '{ "active": false, "reason": "Temporarily disabled for investigation" }'Deleting an exception
To delete an exception:
curl --request DELETE \ --url https://api.azion.com/v4/edge_firewall/wafs/{waf_id}/exceptions/{exception_id} \ --header 'Accept: application/json' \ --header 'Authorization: Token [TOKEN VALUE]'Exception object fields
| Field | Type | Description |
|---|---|---|
id | integer | Unique identifier of the exception (read-only) |
rule_id | integer | The WAF internal rule ID to create an exception for. See the WAF internal rules table for available IDs |
reason | string | A description explaining why this exception was created |
match_zone | string | The part of the request to match against. See Match Zone options |
match_pattern | string | The pattern to match in the specified zone |
path | string | The URL path where the exception applies |
active | boolean | Whether the exception is active (true) or inactive (false) |
| 1400 | Possible trick to evade protection: UTF7/8 encoding &# found in Body, Path, Query String or Cookies. |
| 1401 | Possible trick to evade protection: M$ encoding %U found in Body, Path, Query String or Cookies. |
| 1500 | Possible File Upload attempt: asp/php or .ph, .asp, .ht found in filename in a multipart POST containing a file. |