Operators
Prev | Home | Next

## Operators

A number of operators can be used in rules, as documented below. The operator syntax uses the `@` symbol followed by the specific operator name.

### `beginsWith`

Description: This operator is a string comparison and returns true if the parameter value is found at the beginning of the input. Macro expansion is performed so you may use variable names such as `%{TX.1}`, etc.

Example:

    SecRule REQUEST_LINE "!@beginsWith GET" t:none,deny,status:403
    SecRule REQUEST_ADDR "^(.*)\.\d+$" deny,status:403,capture,chain
    SecRule ARGS:gw "!@beginsWith %{TX.1}"

### `contains`

Description: This operator is a string comparison and returns true if the parameter value is found anywhere in the input. Macro expansion is performed so you may use variable names such as %{TX.1}, etc.

Example:

    SecRule REQUEST_LINE "!@contains .php" t:none,deny,status:403
    SecRule REQUEST_ADDR "^(.*)$" deny,status:403,capture,chain
    SecRule ARGS:ip "!@contains %{TX.1}"

### `endsWith`

Description: This operator is a string comparison and returns true if the parameter value is found at the end of the input. Macro expansion is performed so you may use variable names such as %{TX.1}, etc.

Example:

    SecRule REQUEST_LINE "!@endsWith HTTP/1.1" t:none,deny,status:403
    SecRule ARGS:route "!@endsWith %{REQUEST_ADDR}" t:none,deny,status:403

### `eq`

Description: This operator is a numerical comparison and stands for "equal to."

Example:

    SecRule &REQUEST_HEADERS_NAMES "@eq 15"

Macro expansion is performed so you may use variable names such as `%{TX.1}`, etc.

### `ge`

Description: This operator is a numerical comparison and stands for "greater than or equal to."

Example:

    SecRule &REQUEST_HEADERS_NAMES "@ge 15"

Macro expansion is performed so you may use variable names such as `%{TX.1}`, etc.

### `geoLookup`

Description: This operator looks up various data fields from an IP address or hostname in the target data. The results will be captured in the `GEO` collection.

You must provide a database via `SecGeoLookupDb` before this operator can be used.

### Note

This operator matches and the action is executed on a successful lookup. For this reason, you probably want to use the pass,nolog actions. This allows for `setvar` and other non-disruptive actions to be executed on a match. If you wish to block on a failed lookup, then do something like this (look for an empty GEO collection):

    SecGeoLookupDb /usr/local/geo/data/GeoLiteCity.dat
    ...
    SecRule REMOTE_ADDR "@geoLookup" "pass,nolog"
    SecRule &GEO "@eq 0" "deny,status:403,msg:'Failed to lookup IP'"

See the `GEO` variable for an example and more information on various fields available.

### `gt`

Description: This operator is a numerical comparison and stands for "greater than."

Example:

    SecRule &REQUEST_HEADERS_NAMES "@gt 15"

Macro expansion is performed so you may use variable names such as `%{TX.1}`, etc.

### `inspectFile`

Description: Executes the external script/binary given as parameter to the operator against every file extracted from the request. As of v2.5.0, if the supplied filename is not absolute it is treated as relative to the directory in which the configuration file resides. Also as of v2.5.0, if the filename is determined to be a Lua script (based on its extension) the script will be processed by the internal engine. As such it will have full access to the ModSecurity context.

Example of using an external binary/script:

    # Execute external script to validate uploaded files.
    SecRule FILES_TMPNAMES "@inspectFile /opt/apache/bin/inspect_script.pl"

Example of using Lua script:

    SecRule FILES_TMPNANMES "@inspectFile inspect.lua"

Script `inspect.lua`:

    function main(filename)
        -- Do something to the file to verify it. In this example, we
        -- read up to 10 characters from the beginning of the file.
        local f = io.open(filename, "rb");
        local d = f:read(10);
        f:close();

        -- Return null if there is no reason to believe there is ansything
        -- wrong with the file (no match). Returning any text will be taken
        -- to mean a match should be trigerred.
        return null;
    end

### `le`

Description: This operator is a numerical comparison and stands for "less than or equal to."

Example:

    SecRule &REQUEST_HEADERS_NAMES "@le 15"

Macro expansion is performed so you may use variable names such as `%{TX.1}`, etc.

### `lt`

Description: This operator is a numerical comparison and stands for "less than."

Example:

    SecRule &REQUEST_HEADERS_NAMES "@lt 15"

Macro expansion is performed so you may use variable names such as `%{TX.1}`, etc.

### `pm`

Description: Phrase Match operator. This operator uses a set based matching engine (Aho-Corasick) for faster matches of keyword lists. It will match any one of its arguments anywhere in the target value. The match is case insensitive.

Example:

    SecRule REQUEST_HEADERS:User-Agent "@pm WebZIP WebCopier Webster WebStripper SiteSnagger ProWebWalker CheeseBot" "deny,status:403

The above would deny access with 403 if any of the words matched within the User-Agent HTTP header value.

### `pmFromFile`

Description: Phrase Match operator. This operator uses a set based matching engine (Aho-Corasick) for faster matches of keyword lists. This operator is the same as `@pm` except that it takes a list of files as arguments. It will match any one of the phrases listed in the file(s) anywhere in the target value.

Notes:

1. The contents of the files should be one phrase per line. End of line markers will be stripped from the phrases (LF and CRLF), and whitespace is trimmed from both sides of the phrases. Empty lines and comment lines (beginning with a '#') are ignored.

2. To allow easier inclusion of phrase files with rulesets, relative paths may be used to the phrase files. In this case, the path of the file containing the rule is prepended to the phrase file path.

3. To allow easier matching of whole IP addresses, you can add boundary characters to the phrases. For example, use "/1.2.3.4/" instead of "1.2.3.4". You can then insert these characters into the target prior to a match:

       SecAction "phase:1,pass,nolog,setvar:tx.remote_addr=/%{REMOTE_ADDR}/"
       SecRule TX:REMOTE_ADDR "@pmFromFile ip-blacklist.txt" "deny,status:403

       # ip-blacklist.txt contents:
       # NOTE: All IPs must be prefixed/suffixed with "/" as the rules
       #       will add in this character as a boundary to ensure
       #       the entire IP is matched.
       # SecAction "phase:1,pass,nolog,setvar:tx.remote_addr='/%{REMOTE_ADDR}/'"
       /1.2.3.4/
       /5.6.7.8/

Example:

    SecRule REQUEST_HEADERS:User-Agent "@pm /path/to/blacklist1 blacklist2" "deny,status:403

The above would deny access with 403 if any of the patterns in the two files matched within the User-Agent HTTP header value. The `blacklist2` file would need to be placed in the same path as the file containing the rule.

### `rbl`

Description: Look up the parameter in the RBL given as parameter. Parameter can be an IPv4 address, or a hostname.

Example:

    SecRule REMOTE_ADDR "@rbl sc.surbl.org"

### `rx`

Description: Regular expression operator. This is the default operator, so if the "@" operator is not defined, it is assumed to be rx.

Example:

    SecRule REQUEST_HEADERS:User-Agent "@rx nikto"

Note

Regular expressions are handled by the PCRE library (http://www.pcre.org). ModSecurity compiles its regular expressions with the following settings:

1. The entire input is treated as a single line, even when there are newline characters present.

2. All matches are case-sensitive. If you do not care about case sensitivity you either need to implement the `lowercase` transformation function, or use the per-pattern`(?i)`modifier, as allowed by PCRE.

3. The `PCRE_DOTALL` and `PCRE_DOLLAR_ENDONLY` flags are set during compilation, meaning a single dot will match any character, including the newlines and a `$` end anchor will not match a trailing newline character.

### `streq`

Description: This operator is a string comparison and returns true if the parameter value matches the input exactly. Macro expansion is performed so you may use variable names such as %{TX.1}, etc.

Example:

    SecRule ARGS:foo "!@streq bar" t:none,deny,status:403
    SecRule REQUEST_ADDR "^(.*)$" deny,status:403,capture,chain
    SecRule REQUEST_HEADERS:Ip-Address "!@streq %{TX.1}"

### `validateByteRange`

Description: Validates the byte range used in the variable falls into the specified range.

Example:

    SecRule ARGS:text "@validateByteRange 10, 13, 32-126"

Note

You can force requests to consist only of bytes from a certain byte range. This can be useful to avoid stack overflow attacks (since they usually contain "random" binary content). Default range values are 0 and 255, i.e. all byte values are allowed. This directive does not check byte range in a POST payload when `multipart/form-data` encoding (file upload) is used. Doing so would prevent binary files from being uploaded. However, after the parameters are extracted from such request they are checked for a valid range.

validateByteRange is similar to the ModSecurity 1.X SecFilterForceByteRange Directive however since it works in a rule context, it has the following differences:

- You can specify a different range for different variables.

- It has an "event" context (id, msg....)

- It is executed in the flow of rules rather than being a built in pre-check.

### `validateDTD`

Description: Validates the DOM tree generated by the XML request body processor against the supplied DTD.

Example:

    SecDefaultAction log,deny,status:403,phase:2
    SecRule REQUEST_HEADERS:Content-Type ^text/xml$ \
        phase:1,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML
    SecRule REQBODY_PROCESSOR "!^XML$" nolog,pass,skipAfter:12345
    SecRule XML "@validateDTD /path/to/apache2/conf/xml.dtd" "deny,id:12345"

### Note

This operator requires request body to be processed as XML.

### `validateSchema`

Description: Validates the DOM tree generated by the XML request body processor against the supplied XML Schema.

Example:

    SecDefaultAction log,deny,status:403,phase:2
    SecRule REQUEST_HEADERS:Content-Type ^text/xml$ \
        phase:1,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML
    SecRule REQBODY_PROCESSOR "!^XML$" nolog,pass,skipAfter:12345
    SecRule XML "@validateSchema /path/to/apache2/conf/xml.xsd" "deny,id:12345"

### Note

This operator requires request body to be processed as XML.

### `validateUrlEncoding`

Description: Verifies the encodings used in the variable (if any) are valid.

Example:

    SecRule ARGS "@validateUrlEncoding"

Note

URL encoding is an HTTP standard for encoding byte values within a URL. The byte is escaped with a % followed by two hexadecimal values (0-F). This directive does not check encoding in a POST payload when the `multipart/form-data` encoding (file upload) is used. It is not necessary to do so because URL encoding is not used for this encoding.

### `validateUtf8Encoding`

Description: Verifies the variable is a valid UTF-8 encoded string.

Example:

    SecRule ARGS "@validateUtf8Encoding"

Note

UTF-8 encoding is valid on most web servers. Integer values between 0-65535 are encoded in a UTF-8 byte sequence that is escaped by percents. The short form is two bytes in length.

check for three types of errors:

- Not enough bytes. UTF-8 supports two, three, four, five, and six byte encodings. ModSecurity will locate cases when a byte or more is missing.

- Invalid encoding. The two most significant bits in most characters are supposed to be fixed to 0x80. Attackers can use this to subvert Unicode decoders.

- Overlong characters. ASCII characters are mapped directly into the Unicode space and are thus represented with a single byte. However, most ASCII characters can also be encoded with two, three, four, five, and six characters thus tricking the decoder into thinking that the character is something else (and, presumably, avoiding the security check).

### `verifyCC`

Description: This operator verifies a given regular expression as a potential credit card number. It first matches with a single generic regular expression then runs the resulting match through a Luhn checksum algorithm to further verify it as a potential credit card number.

Example:

    SecRule ARGS "@verifyCC \d{13,16}" \
                  "phase:2,sanitiseMatched,log,auditlog,pass,msg:'Potential credit card number'"

### `within`

Description: This operator is a string comparison and returns true if the input value is found anywhere within the parameter value. Note that this is similar to `@contains`, except that the target and match values are reversed. Macro expansion is performed so you may use variable names such as %{TX.1}, etc.

Example:

    SecRule REQUEST_METHOD "!@within get,post,head" t:lowercase,deny,status:403

    SecAction "pass,setvar:'tx.allowed_methods=get,post,head'"
    SecRule REQUEST_METHOD "!@within %{tx.allowed_methods}" t:lowercase,deny,status:403

Prev |  | Next
Actions | Home | Macro Expansion

Copyright (C) 2004-2010 Breach Security