When one of the Web Application Firewall (WAF) rules are triggered by genuine, non-malicious traffic this is referred to as a false positive.

False positives are a problem because they can cause legitimate user traffic to be blocked, creating a poor user experience. They also make it difficult to spot real attacks against a high background noise of false positives. False positives can also be a compliance issue, for example, if a user’s password causes a false positive and the password is written to the log file as a result.

To resolve a false positive, a rule exclusionis used: this is an instruction to the WAF to adjust its behavior to prevent the false positive from reoccurring.

LoadMaster 360’s smart WAF event filtering identifies false positives when they occur and presents them on the false positive activity page. When a false positive is selected, LoadMaster 360 presents its automatic rule exclusion tooling, making it possible to quickly generate working rule exclusions without the need to write a single line of configuration by hand.

Types of rule exclusions: Startup versus Runtime

There are two main types of rule exclusions that you can apply:

  • Startup rule exclusions instruct the WAF to always ignore certain rules. For example: “never execute rule 1234”. This is useful if rule 1234 causes false positives. (These exclusions are applied at the startupof the WAF and remain in effect.)

  • Runtime rule exclusions instruct the WAF to conditionally ignore certain rules, depending on the location (URI) of a request. For example: “for requests to /login.php, never execute rule 1234”. This is useful if rule 1234 causes false positives specifically at /login.php. (These conditional exclusions are evaluated at runtime for each request.)

    Startup rule exclusions are simple and effective, but they are also quite coarse: rules are disabled unconditionally for all parts of a web application.

    Runtime rule exclusions are more complex, but they are also more fine-grained and targeted: rules are disabled only for the specific locations where they cause false positives and remain enabled (and provide protection) everywhere else.

Exclude ‘by Rule’ or ‘by Target’

When disabling a WAF rule (either for all traffic with a startuprule exclusion or for a specific location with a runtimerule exclusion), the option exists to either disable the entire rule or to disable the rule only for a specific request parameter.

  • Excluding by Rule instructs the WAF to completely ignore a specified rule. For example: “never execute rule 1234”. This is useful if rule 1234 causes false positives. (This can be applied to all traffic as a startup exclusion or for a specific location as a runtime exclusion.)

  • Excluding by Target instructs the WAF to exclude a specific target (a specific part of HTTP requests) from a specified rule. For example: “never execute rule 1234 against the ‘userPassword’ parameter”. This is useful if rule 1234 causes false positives specifically with the userPassword parameter. (This can be applied to all traffic as a startup exclusion or for a specific location as a runtime exclusion.)

The option of excluding either ‘by Rule’ or ‘by Target’ adds an extra dimension to rule exclusions. This option combines with the two main types of rule exclusions (startup or runtime) to create the four Rule exclusion type options that can be selected from the drop-down list in the LoadMaster 360 user interface. These options are:

  • Startup by Rule (completely disable rule for all traffic)

  • Startup by Target (disable rule for a specific parameter for all traffic)

  • Runtime by Rule (completely disable rule for a specific location)

  • Runtime by Target (disable rule for a specific parameter for a specific location)

By Rule

(completely disable rule)

By Target

(disable rule for a specific parameter)

Startup

(apply to all traffic)

Startup by Rule Startup by Target

Runtime

(apply to a specific location)

Runtime by Rule Runtime by Target

The four ‘Rule exclusion type’ drop-down options

To demonstrate how to use the four different rule exclusion options, we will use the following simplified example of a false positive:

Warning. Matched phrase "dev/null" at ARGS:querystring. [id "932160"] [msg "Remote Command Execution: Unix Shell Code Found"] [data "Matched Data: dev/null found within ARGS:querystring: what does/dev/null do"] [uri "/search"] 

This is a typical example of the kind of false positive that can occur when handling free-form user input. In this example, a user has submitted “what does /dev/null do” in a search bar. This is a valid search query in the context of a search bar but the WAF lacks that context. The WAF rule with ID 932160 matches against the pattern “/dev/null” (a special device file present on Unix-based systems) and causes the false positive.

Startup by Rule

For all traffic, completely disable the specified rule.

This option is very coarse and simple.

Example rule exclusion generated by LoadMaster 360:

# ModSec Rule Exclusion: 932160 : Remote Command Execution: Unix Shell Code Found
SecRuleRemoveById 932160

You can then add this rule exclusion as a custom WAF rule to the LoadMaster.

The offending WAF rule (932160) will be completely disabled. The false positive cannot reoccur.

Best used when:

  • The offending rule is irrelevant (for example, a Unix rule when the back-end web app is 100% Windows Server based, or a PHP rule when absolutely no PHP is in use.)

  • Keeping things as simple as possible.

Runtime by Rule

For a specific location only, completely disable the specified rule.

This option is fairly specific and simple.

Example rule exclusion generated by LoadMaster 360:

# ModSec Rule Exclusion: 932160 : Remote Command Execution: Unix Shell Code Found
SecRule REQUEST_URI "@beginsWith /search" "phase:1,nolog,pass,id:1000,ctl:ruleRemoveById=932160"

You can then add this rule exclusion as a custom “Run First” WAF rule to the LoadMaster.

For the location ‘/search’ only, the offending WAF rule (932160) will be disabled. The rule remains enabled and provides protection for all other locations. The false positive cannot reoccur on the ‘/search’ page.

Best used when:

  • A false positive is confined to a specific location/URI.

  • The offending rule can provide useful protection for the rest of the web app, so the simpler approach of disabling the rule entirely is undesirable.

Startup by Target

For all traffic, exclude a specific target (a specific part of HTTP requests) from the specified rule.

This option is fairly coarse and simple.

Example rule exclusion generated by LoadMaster 360:

# ModSec Rule Exclusion: 932160 : Remote Command Execution: Unix Shell Code Found
SecRuleUpdateTargetById 932160 "!ARGS:querystring"

This rule exclusion can then be added as a custom WAF rule to the LoadMaster.

The ‘querystring’ argument will be excluded from the offending WAF rule (932160). The rule remains enabled and will inspect all other parts of HTTP requests as normal. The false positive cannot reoccur for the argument ‘querystring’.

Best used when:

  • The same, specific part of request traffic causes a false positive, maybe across multiple locations (for example, a request cookie whose random value is prone to causing false positives and can appear at every possible location a user can access.)

Runtime by Target

For a specific location only, exclude a specific target (a specific part of HTTP requests) from the specified rule.

This option is very fine-grained and fairly complex.

Example rule exclusion generated by LoadMaster 360:

# ModSec Rule Exclusion: 932160 : Remote Command Execution: Unix Shell Code Found
SecRule REQUEST_URI "@beginsWith /search" "phase:1,nolog,pass,id:1000,ctl:ruleRemoveTargetById=932160;ARGS:querystring"

You can then add this rule exclusion as a custom “Run First” WAF rule to the LoadMaster.

For the location ‘/search’ only, the ‘querystring’ argument will be excluded from the offending WAF rule (932160). For the ‘/search’ page, the rule remains enabled and will inspect all other parts of HTTP requests as normal. For all other locations, the rule remains fully enabled and provides protection. (A ‘querystring’ argument on a differentpage would cause a new false positive, for example.) The false positive cannot reoccur on the ‘/search’ page for the argument ‘querystring’.

Best used when:

  • A false positive is confined to a specific location/URI andis confined to the same, specific part of request traffic (for example, a ‘password’ field at location ‘/login.php’ causes false positives, but for any other location a ‘password’ parameter is not expected and should be fully inspected by the WAF.)

  • The offending rule can provide useful protection for the rest of the web app, so the simpler approaches of disabling the rule entirely or excluding the specific target entirely are undesirable.

The 'Runtime Rule ID' and 'Metadata' options

Runtime Rule ID

The conditional, location-based “runtime” rule exclusions take the form of WAF rules themselves. All WAF rules are required to have a unique ID number. The “Runtime Rule ID” spinner defines the rule ID number that should be used for the (first) generated rule exclusion.

As an example, if a LoadMaster WAF service already has 10 runtime exclusion rules in place starting from the default rule ID of 1000 and ending at 1009 then the “runtime rule ID” could be set to 1010 to ensure that the newly-generated runtime rule exclusions do not clash with the existing range of rule IDs.

Metadata

Checking the Metadata check box inserts additional data from the false positive log alert into the rule exclusion that is generated, for example, the URI of the alert and its unique ID in the log file. This makes it easier to:
  • Understand the rationale behind rule exclusions in the future
  • Refer to relevant alerts and log lines at a later time

By Id or By Tag

The default (and simplest) way to exclude rules is by ID. This uses the unique ID number of an offending rule and disables that rule in some way, as described above (for example, completely disabling the rule, disabling the rule for a specific location only, and so on.)

The alternative to excluding rules by ID (the default mode) is to exclude rules by tag. This additional option of ‘By Id’ versus ‘By Tag’ adds a third dimension to creating rule exclusions. This effectively doubles the four exclusion types described above to eight: ‘startup by rule by ID’, ‘startup by rule by tag’, ‘runtime by rule by ID’, and so on.

WAF rules feature multiple tags to group them together into meaningful categories. For example: “language-php” groups all of the PHP rules together, “attack-sqli” groups together all of the rules for detecting SQL injection attacks, and so on.

When the By Tag radio button is selected, a new drop-down list appears: Generate rule tag. This drop-down list is automatically populated with all of the tags present in the offending WAF rule. When a specific tag is selected, the rule exclusion that is generated will have the effect of disabling that entire category of WAF rules.

Example

Using the earlier example false positive for the pattern “/dev/null”, assume that the back-end application behind the WAF makes no use of Unix-like systems whatsoever. As such, all WAF rules searching for Unix-related attacks can be disabled to reduce the risk of false positives occurring.

To achieve this, click the By Tag radio button and then, from the Generate rule tag drop-down list, choose the rule tag platform-unix. This will generate the following rule exclusion:

# ModSec Rule Exclusion : 932160 via tag "platform-unix" (Msg: Remote Command Execution: Unix Shell Code Found)
SecRuleRemoveByTag platform-unix

Once this rule exclusion has been added as a custom WAF rule to the LoadMaster, the exclusion will disable all rules tagged as “platform-unix” and none of the Unix-related attack detection rules will be executed in the future.

Altered meanings of the ‘Rule exclusion type’ options 'By Tag'

Switching to the By Tag option modifies the meaning of the four “rule exclusion types” as follows:

  • Startup by Rule… by Tag: For all traffic, completely disable the entire category of rules.

  • Startup by Target… by Tag: For all traffic, exclude a specific target (a specific part of HTTP requests) from the entire category of rules.

  • Runtime by Rule… by Tag: For a specific location only, completely disable the entire category of rules.

  • Runtime by Target… by Tag: For a specific location only, exclude a specific target (a specific part of HTTP requests) from the entire category of rules.