From df58972abfeff4e37b50707310ed6e7614c10689 Mon Sep 17 00:00:00 2001
From: brenosilva
Syntax: SecRule VARIABLES OPERATOR [ACTIONS]
Example Usage: SecRule ARGS "@rx attack"
-"phase:1,log,deny"
+"phase:1,log,deny,id:1"
Scope: Any
Version: 2.0.0
Every rule must provide one or more variables along with the @@ -2829,16 +2829,18 @@ target to the end of the variable list as follows:
You could also do the same by using the ctl action. This is useful if you want to only update the targets for a particular URL
-SecRule REQUEST_FILENAME "@streq /path/to/file.php" "phase:1,t:none,nolog,pass,ctl:ruleUpdateTargetById=958895;!ARGS:email" +SecRule REQUEST_FILENAME "@streq /path/to/file.php" "phase:1,id:2,t:none,nolog,pass,ctl:ruleUpdateTargetById=958895;!ARGS:email"Conditionally Replacing Targets
You could also replace targets using the ctl action. For example, lets say you want to only inspect ARGS for a particular URL:
-SecRule REQUEST_FILENAME "@streq /path/to/file.php" "phase:1,t:none,nolog,pass,ctl:ruleUpdateTargetById=958895;REQUEST_URI;REQUEST_FILENAME" +SecRule REQUEST_FILENAME "@streq /path/to/file.php" "phase:1,id:3,t:none,nolog,pass,ctl:ruleUpdateTargetById=958895;REQUEST_URI;REQUEST_FILENAME"
SecDefaultAction "log,pass,phase:2" -SecRule REQUEST_HEADERS:Host "!^$" "deny,phase:1" +SecDefaultAction "log,pass,phase:2,id:4" +SecRule REQUEST_HEADERS:Host "!^$" "deny,phase:1,id:5"
Some variables are actually collections, which are expanded into more variables at runtime. The following example will examine all request arguments: -
SecRule ARGS dirty
+
SecRule ARGS dirty "id:7"
Sometimes, however, you will want to look only at parts of a collection. This can be achieved with the help of the selection operator(colon). The following example will only look at the arguments named p (do note that, in general, requests can contain multiple arguments with the same name): -
SecRule ARGS:p dirty
+
SecRule ARGS:p dirty "id:8"
It is also possible to specify exclusions. The following will examine all request arguments for the word dirty, except the ones named z (again, there can be zero or more arguments named z): -
SecRule ARGS|!ARGS:z dirty
+
SecRule ARGS|!ARGS:z dirty "id:9"
There is a special operator that allows you to count how many variables there are in a collection. The following rule will trigger if there is more than zero arguments in the request (ignore the second parameter for the time being): -
SecRule &ARGS !^0$
+
SecRule &ARGS !^0$ "id:10"
And sometimes you need to look at an array of parameters, each with a slightly different name. In this case you can specify a regular expression in the selection operator itself. The following rule will look into all arguments whose names begin with id_: -
SecRule ARGS:/^id_/ dirty
+
SecRule ARGS:/^id_/ dirty "id:11"
SecRule ARGS_COMBINED_SIZE "@gt 2500"
+
SecRule ARGS_COMBINED_SIZE "@gt 2500" "id:12"
SecRule ARGS_NAMES "!^(p|a)$"
+
SecRule ARGS_NAMES "!^(p|a)$" "id:13"
SecRule AUTH_TYPE "Basic"
+
SecRule AUTH_TYPE "Basic" "id:14"
# Set environment variable SecRule REQUEST_FILENAME "printenv" \ -"phase:2,pass,setenv:tag=suspicious" +"phase:2,id:15,pass,setenv:tag=suspicious" # Inspect environment variable -SecRule ENV:tag "suspicious" +SecRule ENV:tag "suspicious" "id:16"
Contains a collection of original file names (as they were called on the remote user’s filesys- tem). Available only on inspected multipart/form-data requests. -
SecRule FILES "@rx \.conf$"
+
SecRule FILES "@rx \.conf$" "id:17"
Contains the total size of the files transported in request body. Available only on inspected multipart/form-data requests. -
SecRule FILES_COMBINED_SIZE "@gt 100000"
+
SecRule FILES_COMBINED_SIZE "@gt 100000" "id:18"
Contains a list of form fields that were used for file upload. Available only on inspected multipart/form-data requests. -
SecRule FILES_NAMES "^upfile$"
+
SecRule FILES_NAMES "^upfile$" "id:19"
Contains a list of individual file sizes. Useful for implementing a size limitation on individual uploaded files. Available only on inspected multipart/form-data requests. -
SecRule FILES_SIZES "@gt 100"
+
SecRule FILES_SIZES "@gt 100" "id:20"
SecRule FILES_TMPNAMES "@inspectFile
-/path/to/inspect_script.pl"
+/path/to/inspect_script.pl" "id:21"
GEO is a collection populated by the results of the last @geoLookup @@ -3415,7 +3417,7 @@ database. (US only)
SecGeoLookupDb /usr/local/geo/data/GeoLiteCity.dat ... -SecRule REMOTE_ADDR "@geoLookup" "chain,drop,msg:'Non-GB IP address'" +SecRule REMOTE_ADDR "@geoLookup" "chain,id:22,drop,msg:'Non-GB IP address'" SecRule GEO:COUNTRY_CODE "!@streq GB"
SecRule HIGHEST_SEVERITY "@le 2"
-"phase:2,deny,status:500,msg:'severity %{HIGHEST_SEVERITY}'"
+"phase:2,id:23,deny,status:500,msg:'severity %{HIGHEST_SEVERITY}'"
The best way to use this variable is as in the example below:
SecRule INBOUND_DATA_ERROR "@eq 1"
-"phase:1,t:none,log,pass,msg:'Request Body Larger than
+"phase:1,id:24,t:none,log,pass,msg:'Request Body Larger than
SecRequestBodyLimit Setting'"
SecRule ARGS pattern chain,deny +SecRule ARGS pattern chain,deny,id:25 SecRule MATCHED_VAR "further scrutiny"
Similar to MATCHED_VAR except that it is a collection of all matches for the current operator check.
-SecRule ARGS pattern "chain,deny" +SecRule ARGS pattern "chain,deny,id:26" SecRule MATCHED_VARS "@eq ARGS:param"MATCHED_VAR_NAME
This variable holds the full name of the variable that was matched against.
-SecRule ARGS pattern "chain,deny" +SecRule ARGS pattern "chain,deny,id:27" SecRule MATCHED_VAR_NAME "@eq ARGS:param"
Similar to MATCHED_VAR_NAME except that it is a collection of all matches for the current operator check.
-SecRule ARGS pattern "chain,deny" +SecRule ARGS pattern "chain,deny,id:28" SecRule MATCHED_VARS_NAMES "@eq ARGS:param"MODSEC_BUILD
intended to be used to check the build number prior to using a feature that is available only in a certain build. Example: -SecRule MODSEC_BUILD "!@ge 02050102" "skipAfter:12345" +SecRule MODSEC_BUILD "!@ge 02050102" "skipAfter:12345,id:29" SecRule ARGS "@pm some key words" "id:12345,deny,status:500"
The best way to use this variable is as in the example below:
SecRule MULTIPART_STRICT_ERROR "!@eq 0" \ -"phase:2,t:none,log,deny,msg:'Multipart request body \ +"phase:2,id:30,t:none,log,deny,msg:'Multipart request body \ failed strict validation: \ PE %{REQBODY_PROCESSOR_ERROR}, \ BQ %{MULTIPART_BOUNDARY_QUOTED}, \ @@ -3555,7 +3557,7 @@ ModSecurity encounters what feels like a boundary but it is not. Such anThe best way to use this variable is as in the example below:
SecRule MULTIPART_UNMATCHED_BOUNDARY "!@eq 0" \ -"phase:2,t:none,log,deny,msg:'Multipart parser detected a possible unmatched boundary.'" +"phase:2,id:31,t:none,log,deny,msg:'Multipart parser detected a possible unmatched boundary.'"Change the rule from blocking to logging-only if many false positives are encountered. @@ -3569,7 +3571,7 @@ rate of false positives and your default policy you should decide whether to block or just warn when the rule is triggered.
The best way to use this variable is as in the example below:
SecRule OUTBOUND_DATA_ERROR "@eq 1" -"phase:1,t:none,log,pass,msg:'Response Body Larger than +"phase:1,id:32,t:none,log,pass,msg:'Response Body Larger than SecResponseBodyLimit Setting'"
@@ -3577,7 +3579,7 @@ PATH_INFO
Contains the extra request URI information, also known as path info. (For example, in the URI /index.php/123, /123 is the path info.) Available only in embedded deployments. -
SecRule PATH_INFO "^/(bin|etc|sbin|opt|usr)"
+
SecRule PATH_INFO "^/(bin|etc|sbin|opt|usr)" "id:33"
PERF_COMBINED
@@ -3644,12 +3646,12 @@ storage. Available starting with 2.6. class="mw-headline"> QUERY_STRINGContains the query string part of a request URI. The value in QUERY_STRING is always provided raw, without URL decoding taking place. -
SecRule QUERY_STRING "attack"
+
SecRule QUERY_STRING "attack" "id:34"
REMOTE_ADDR
This variable holds the IP address of the remote client. -
SecRule REMOTE_ADDR "@ipMatch 192.168.1.101"
+
SecRule REMOTE_ADDR "@ipMatch 192.168.1.101" "id:35"
REMOTE_HOST
@@ -3659,7 +3661,7 @@ directive is set to Off, this variable it will hold the remote IP address (same as REMOTE_ADDR). Possible uses for this variable would be to deny known bad client hosts or network blocks, or conversely, to allow in authorized hosts. -
SecRule REMOTE_HOST "\.evil\.network\org$"
+
SecRule REMOTE_HOST "\.evil\.network\org$" "id:36"
REMOTE_PORT
@@ -3668,14 +3670,14 @@ used when initiating the connection to our web server.In the following example, we are evaluating to see whether the REMOTE_PORT is less than 1024, which would indicate that the user is a privileged user: -
SecRule REMOTE_PORT "@lt 1024"
+
SecRule REMOTE_PORT "@lt 1024" "id:37"
REMOTE_USER
This variable holds the username of the authenticated user. If there are no password access controls in place (Basic or Digest authentication), then this variable will be empty. -
SecRule REMOTE_USER "^admin$"
+
SecRule REMOTE_USER "^admin$" "id:38"
SecRule REQBODY_ERROR "@eq 1" deny,phase:2
+
SecRule REQBODY_ERROR "@eq 1" deny,phase:2,id:39
If there’s been an error during request body parsing, the variable will contain the following error message: -
SecRule REQBODY_ERROR_MSG "failed to parse"
+
SecRule REQBODY_ERROR_MSG "failed to parse" "id:40"
Contains the name of the currently used request body processor. The possible values are URLENCODED, MULTIPART, and XML.
-SecRule REQBODY_PROCESSOR "^XML$ chain +SecRule REQBODY_PROCESSOR "^XML$ chain,id:41 SecRule XML "@validateDTD /opt/apache-frontend/conf/xml.dtd"REQUEST_BASENAME
This variable holds just the filename part of REQUEST_FILENAME (e.g., index.php).
SecRule REQUEST_BASENAME "^login\.php$" -phase:2,t:none,t:lowercase
+phase:2,id:42,t:none,t:lowercase
SecRule REQUEST_BODY
-"^username=\w{25,}\&password=\w{25,}\&Submit\=login$"
+"^username=\w{25,}\&password=\w{25,}\&Submit\=login$" "id:43"
As of 2.5.7, it is possible to force the presence of the REQUEST_BODY variable, but only when there is no request body processor defined using the ctl:forceRequestBodyVariable option in the @@ -3754,21 +3756,22 @@ only). Example: the following example is using the Ampersand special operator to count how many variables are in the collection. In this rule, it would trigger if the request does not include any Cookie headers. -
SecRule &REQUEST_COOKIES "@eq 0"
+
SecRule &REQUEST_COOKIES "@eq 0" "id:44"
This variable is a collection of the names of all request cookies. For example, the following rule will trigger if the JSESSIONID cookie is not present: -
SecRule &REQUEST_COOKIES_NAMES:JSESSIONID "@eq 0"
+
SecRule &REQUEST_COOKIES_NAMES:JSESSIONID "@eq 0"
+"id:45"
This variable holds the relative request URL without the query string part (e.g., /index.php).
SecRule REQUEST_FILENAME "^/cgi-bin/login\.php$"
-phase:2,t:none,t:normalizePath
+phase:2,id:46,t:none,t:normalizePath
SecRule REQUEST_HEADERS:Host "^[\d\.]+$"
-"deny,log,status:400,msg:'Host header is a numeric IP address'"
+"deny,id:47,log,status:400,msg:'Host header is a numeric IP address'"
This variable is a collection of the names of all of the request headers.
SecRule REQUEST_HEADERS_NAMES "^x-forwarded-for"
-"log,deny,status:403,t:lowercase,msg:'Proxy Server Used'"
+"log,deny,id:48,status:403,t:lowercase,msg:'Proxy Server Used'"
# Allow only POST, GET and HEAD request methods, as well as only # the valid protocol versions -SecRule REQUEST_LINE "!(^((?:(?:POS|GE)T|HEAD))|HTTP/(0\.9|1\.0|1\.1)$)" "phase:1,log,block,t:none" +SecRule REQUEST_LINE "!(^((?:(?:POS|GE)T|HEAD))|HTTP/(0\.9|1\.0|1\.1)$)" "phase:1,id:49,log,block,t:none"
This variable holds the request method used in the transaction. -
SecRule REQUEST_METHOD "^(?:CONNECT|TRACE)$" "t:none"
+
SecRule REQUEST_METHOD "^(?:CONNECT|TRACE)$" "id:50,t:none"
This variable holds the request protocol version information. -
SecRule REQUEST_PROTOCOL "!^HTTP/(0\.9|1\.0|1\.1)$"
+
SecRule REQUEST_PROTOCOL "!^HTTP/(0\.9|1\.0|1\.1)$" "id:51"
SecRule REQUEST_URI "attack"
-"phase:1,t:none,t:urlDecode,t:lowercase,t:normalizePath"
+"phase:1,id:52,t:none,t:urlDecode,t:lowercase,t:normalizePath"
SecRule REQUEST_URI_RAW "http:/"
-"phase:1,t:none,t:urlDecode,t:lowercase,t:normalizePath"
+"phase:1,id:53,t:none,t:urlDecode,t:lowercase,t:normalizePath"
This variable holds the data for the response body, but only when response body buffering is enabled. -
SecRule RESPONSE_BODY "ODBC Error Code" "phase:4,t:none"
+
SecRule RESPONSE_BODY "ODBC Error Code"
+"phase:4,id:54,t:none"
This variable refers to response headers, in the same way as REQUEST_HEADERS does to request headers. -
SecRule RESPONSE_HEADERS:X-Cache "MISS"
+
SecRule RESPONSE_HEADERS:X-Cache "MISS" "id:55"
This variable may not have access to some headers when running in embedded mode. Headers such as Server, Date, Connection, and Content-Type could be added just prior to sending the data to the @@ -3874,19 +3878,20 @@ proxy mode. class="mw-headline"> RESPONSE_HEADERS_NAMES
This variable is a collection of the response header names.
SecRule RESPONSE_HEADERS_NAMES "Set-Cookie"
-"phase:3,t:none"
+"phase:3,id:56,t:none"
The same limitations apply as the ones discussed in RESPONSE_HEADERS.
This variable holds the HTTP response protocol information. -
SecRule RESPONSE_PROTOCOL "^HTTP\/0\.9" "phase:3,t:none"
+
SecRule RESPONSE_PROTOCOL "^HTTP\/0\.9"
+"phase:3,id:57,t:none"
This variable holds the HTTP response status code: -
SecRule RESPONSE_STATUS "^[45]" "phase:3,t:none"
+
SecRule RESPONSE_STATUS "^[45]" "phase:3,id:58,t:none"
This variable may not work as expected in embedded mode, as Apache sometimes handles certain requests differently, and without invoking ModSecurity (all other modules). @@ -3896,12 +3901,12 @@ invoking ModSecurity (all other modules). severity, logdata, and msg fields of the rule that triggered the action. It can be used to refer to only the same rule in which it resides.
SecRule &REQUEST_HEADERS:Host "@eq 0"
-"log,deny,setvar:tx.varname=%{RULE.id}"
+"log,deny,id:59,setvar:tx.varname=%{RULE.id}"
This variable holds just the local filename part of SCRIPT_FILENAME. -
SecRule SCRIPT_BASENAME "^login\.php$"
+
SecRule SCRIPT_BASENAME "^login\.php$" "id:60"
This variable holds the full internal path to the script that will be used to serve the request.
SecRule SCRIPT_FILENAME
-"^/usr/local/apache/cgi-bin/login\.php$"
+"^/usr/local/apache/cgi-bin/login\.php$" "id:61"
This variable holds the numerical identifier of the group owner of the script. -
SecRule SCRIPT_GID "!^46$"
+
SecRule SCRIPT_GID "!^46$" "id:62"
This variable holds the name of the group owner of the script. -
SecRule SCRIPT_GROUPNAME "!^apache$"
+
SecRule SCRIPT_GROUPNAME "!^apache$" "id:63"
This variable holds the script’s permissions mode data (e.g., 644).
# Do not allow scripts that can be written to -SecRule SCRIPT_MODE "^(2|3|6|7)$" +SecRule SCRIPT_MODE "^(2|3|6|7)$" "id:64"
# Do not run any scripts that are owned # by Apache (Apache's user id is 46) -SecRule SCRIPT_UID "!^46$" +SecRule SCRIPT_UID "!^46$" "id:65"
This variable holds the username of the owner of the script.
# Do not run any scripts owned by Apache SecRule -SCRIPT_USERNAME "^apache$" +SCRIPT_USERNAME "^apache$" "id:66"
This variable contains the IP address of the server. -
SecRule SERVER_ADDR "@ipMatch 192.168.1.100"
+
SecRule SERVER_ADDR "@ipMatch 192.168.1.100" "id:67"
This variable contains the transaction’s hostname or IP address, taken from the request itself (which means that, in principle, it should not be trusted). -
SecRule SERVER_NAME "hostname\.com$"
+
SecRule SERVER_NAME "hostname\.com$" "id:68"
This variable contains the local port that the web server (or reverse proxy) is listening on. -
SecRule SERVER_PORT "^80$"
+
SecRule SERVER_PORT "^80$" "id:69"
# Initialize session storage -SecRule REQUEST_COOKIES:PHPSESSID !^$ "phase:2,nolog,pass,setsid:%{REQUEST_COOKIES.PHPSESSID}" +SecRule REQUEST_COOKIES:PHPSESSID !^$ "phase:2,id:70,nolog,pass,setsid:%{REQUEST_COOKIES.PHPSESSID}" # Increment session score on attack -SecRule REQUEST_URI "^/cgi-bin/finger$" "phase:2,t:none,t:lowercase,t:normalizePath,pass,setvar:SESSION.score=+10" +SecRule REQUEST_URI "^/cgi-bin/finger$" "phase:2,id:71,t:none,t:lowercase,t:normalizePath,pass,setvar:SESSION.score=+10" # Detect too many attacks in a session -SecRule SESSION:score "@gt 50" "phase:2,pass,setvar:SESSION.blocked=1" +SecRule SESSION:score "@gt 50" "phase:2,id:72,pass,setvar:SESSION.blocked=1" # Enforce session block -SecRule SESSION:blocked "@eq 1" "phase:2,deny,status:403" +SecRule SESSION:blocked "@eq 1" "phase:2,id:73,deny,status:403"
This variable holds a formatted string representing the time (hour:minute:second). -
SecRule TIME "^(([1](8|9))|([2](0|1|2|3))):\d{2}:\d{2}$"
+
SecRule TIME "^(([1](8|9))|([2](0|1|2|3))):\d{2}:\d{2}$"
+"id:74"
This variable holds the current date (1–31). The following rule triggers on a transaction that’s happening anytime between the 10th and 20th in a month: -
SecRule TIME_DAY "^(([1](0|1|2|3|4|5|6|7|8|9))|20)$"
+
SecRule TIME_DAY "^(([1](0|1|2|3|4|5|6|7|8|9))|20)$"
+"id:75"
This variable holds the current hour value (0–23). The following rule triggers when a request is made “off hours”: -
SecRule TIME_HOUR "^(0|1|2|3|4|5|6|[1](8|9)|[2](0|1|2|3))$"
+
SecRule TIME_HOUR "^(0|1|2|3|4|5|6|[1](8|9)|[2](0|1|2|3))$"
+ "id:76"
This variable holds the current minute value (0–59). The following rule triggers during the last half hour of every hour: -
SecRule TIME_MIN "^(3|4|5)"
+
SecRule TIME_MIN "^(3|4|5)" "id:77"
This variable holds the current month value (0–11). The following rule matches if the month is either November (value 10) or December (value 11): -
SecRule TIME_MON "^1"
+
SecRule TIME_MON "^1" "id:78"
This variable holds the current second value (0–59). -
SecRule TIME_SEC "@gt 30"
+
SecRule TIME_SEC "@gt 30" "id:79"
This variable holds the current weekday value (0–6). The following rule triggers only on Satur- day and Sunday: -
SecRule TIME_WDAY "^(0|6)$"
+
SecRule TIME_WDAY "^(0|6)$" "id:80"
This variable holds the current four-digit year value. -
SecRule TIME_YEAR "^2006$"
+
SecRule TIME_YEAR "^2006$" "id:81"
This is the transient transaction collection, which is used to store @@ -4088,10 +4096,10 @@ variables placed into this collection are available only until the transaction is complete.
# Increment transaction attack score on attack -SecRule ARGS attack "phase:2,nolog,pass,setvar:TX.score=+5" +SecRule ARGS attack "phase:2,id:82,nolog,pass,setvar:TX.score=+5" # Block the transactions whose scores are too high -SecRule TX:SCORE "@gt 20" "phase:2,log,deny" +SecRule TX:SCORE "@gt 20" "phase:2,id:83,log,deny"
Some variable names in the TX collection are reserved and cannot be used: @@ -4132,10 +4140,10 @@ the requests that use the URLENCODED request body processor).
This variable contains the value set with setuid.
# Initialize user tracking -SecAction "nolog,pass,setuid:%{REMOTE_USER}" +SecAction "nolog,id:84,pass,setuid:%{REMOTE_USER}" # Is the current user the administrator? -SecRule USERID "admin" +SecRule USERID "admin" "id:85"
Contains zero or more error messages produced by the web server. This variable is best accessed from phase 5 (logging).
SecRule WEBSERVER_ERROR_LOG "File does not exist"
-"phase:5,t:none,nolog,pass,setvar:TX.score=+5"
+"phase:5,id:86,t:none,nolog,pass,setvar:TX.score=+5"
Special collection used to interact with the XML parser. It can be @@ -4161,11 +4169,11 @@ used standalone as a target for the validateDTD and validateSchema operator. Otherwise, it must contain a valid XPath expression, which will then be evaluated against a previously parsed XML DOM tree.
-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$" skipAfter:12345 +SecDefaultAction log,deny,status:403,phase:2,id:90 +SecRule REQUEST_HEADERS:Content-Type ^text/xml$ "phase:1,id:87,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML" +SecRule REQBODY_PROCESSOR "!^XML$" skipAfter:12345,id:88 -SecRule XML:/employees/employee/name/text() Fred +SecRule XML:/employees/employee/name/text() Fred "id:89" SecRule XML:/xq:employees/employee/name/text() Fred "id:12345,xmlns:xq=http://www.example.com/employees"The first XPath expression does not use namespaces. It would match @@ -4231,7 +4239,7 @@ functions, as there were in the first generation of ModSecurity (1.x).
In the following example, the request parameter values are converted to lowercase before matching: -
SecRule ARGS "xp_cmdshell" "t:lowercase"
+
SecRule ARGS "xp_cmdshell" "t:lowercase,id:91"
Multiple transformation actions can be used in the same rule, forming a transformation pipeline. The transformations will be performed in the order in which they appear in the rule. @@ -4242,7 +4250,7 @@ transformations in any other order would allow a skillful attacker to evade detection:
SecRule ARGS
"(asfunction|javascript|vbscript|data|mocha|livescript):"
-"t:none,t:htmlEntityDecode,t:lowercase,t:removeNulls,t:removeWhitespace"
+"id:92,t:none,t:htmlEntityDecode,t:lowercase,t:removeNulls,t:removeWhitespace"
Decodes a Base64-encoded string.
-SecRule REQUEST_HEADERS:Authorization "^Basic ([a-zA-Z0-9]+=*)$" "phase:1,capture,chain,logdata:%{TX.1}" +SecRule REQUEST_HEADERS:Authorization "^Basic ([a-zA-Z0-9]+=*)$" "phase:1,id:93,capture,chain,logdata:%{TX.1}" SecRule TX:1 ^(\w+): t:base64Decode,capture,chain SecRule TX:1 ^(admin|root|backup)$@@ -4315,7 +4323,7 @@ into one spaceExample Usage:
-SecRule ARGS "(?:command(?:.com)?|cmd(?:.exe)?)(?:/.*)?/[ck]" "phase:2,t:none, t:cmdLine" +SecRule ARGS "(?:command(?:.com)?|cmd(?:.exe)?)(?:/.*)?/[ck]" "phase:2,id:94,t:none, t:cmdLine"compressWhitespace
@@ -4553,7 +4561,7 @@ allows the transaction to proceed.Example:
# Allow unrestricted access from 192.168.1.100 -SecRule REMOTE_ADDR "^192\.168\.1\.100$" phase:1,nolog,allow +SecRule REMOTE_ADDR "^192\.168\.1\.100$" phase:1,id:95,nolog,allow
Prior to ModSecurity 2.5 the allow action would only affect the current @@ -4575,16 +4583,16 @@ will be phase RESPONSE_HEADERS.Examples:
# Do not process request but process response. -SecAction phase:1,allow:request +SecAction phase:1,allow:request,id:96 # Do not process transaction (request and response). -SecAction phase:1,allow +SecAction phase:1,allow,id:97If you want to allow a response through, put a rule in phase RESPONSE_HEADERS and simply use allow on its own:
# Allow response through. -SecAction phase:3,allow +SecAction phase:3,allow,id:98append
Description: Appends text given as parameter to the end of @@ -4597,7 +4605,7 @@ injection.
Processing Phases: 3 and 4.
Example:
-SecRule RESPONSE_CONTENT_TYPE "^text/html" "nolog,pass,append:'<hr>Footer'"+SecRule RESPONSE_CONTENT_TYPE "^text/html" "nolog,id:99,pass,append:'<hr>Footer'"
Action Group: Non-disruptive
Example:
SecRule REMOTE_ADDR "^192\.168\.1\.100$"
-auditlog,phase:1,allow
+auditlog,phase:1,id:100,allow
Examples:
# Specify how blocking is to be done -SecDefaultAction phase:2,deny,status:403,log,auditlog +SecDefaultAction phase:2,deny,id:101,status:403,log,auditlog # Detect attacks where we want to block -SecRule ARGS attack1 phase:2,block +SecRule ARGS attack1 phase:2,block,id:102 # Detect attacks where we want only to warn -SecRule ARGS attack2 phase:2,pass +SecRule ARGS attack2 phase:2,pass,id:103
It is possible to use the SecRuleUpdateActionById directive to override how a rule handles blocking. This is useful in three cases: @@ -4649,7 +4657,7 @@ policy you determine hard-coded block is removed in favor of the user-controllable block:
# Specify how blocking is to be done -SecDefaultAction phase:2,deny,status:403,log,auditlog +SecDefaultAction phase:2,deny,status:403,log,auditlog,id:104 # Detect attacks and block SecRule ARGS attack1 phase:2,id:1,deny @@ -4666,7 +4674,7 @@ collection.Action Group: Non-disruptive
Example:
-SecRule REQUEST_BODY "^username=(\w{25,})" phase:2,capture,t:none,chain +SecRule REQUEST_BODY "^username=(\w{25,})" phase:2,capture,t:none,chain,id:105 SecRule TX:1 "(?:(?:a(dmin|nonymous)))"Up to 10 captures will be copied on a successful pattern match, each @@ -4685,7 +4693,7 @@ more complex processing logic.
# Refuse to accept POST requests that do not contain Content-Length header. # (Do note that this rule should be preceded by a rule # that verifies only valid request methods are used.) -SecRule REQUEST_METHOD "^POST$" phase:1,chain,t:none +SecRule REQUEST_METHOD "^POST$" phase:1,chain,t:none,id:105 SecRule &REQUEST_HEADERS:Content-Length "@eq 0" t:none
Example:
# Parse requests with Content-Type "text/xml" as XML -SecRule REQUEST_CONTENT_TYPE ^text/xml "nolog,pass,ctl:requestBodyProcessor=XML" +SecRule REQUEST_CONTENT_TYPE ^text/xml "nolog,pass,id:106,ctl:requestBodyProcessor=XML"
The following configuration options are supported:
@@ -4776,8 +4784,8 @@ types.Description: Stops rule processing and intercepts transaction.
Action Group: Disruptive
Example:
-SecRule REQUEST_HEADERS:User-Agent "nikto" "log,deny,msg:'Nikto
-Scanners Identified'"
+SecRule REQUEST_HEADERS:User-Agent "nikto"
+"log,deny,id:107,msg:'Nikto Scanners Identified'"
Example: The following example will decrement the counter by 60 every 300 seconds.
-SecAction phase:5,nolog,pass,deprecatevar:SESSION.score=60/300 +SecAction phase:5,id:108,nolog,pass,deprecatevar:SESSION.score=60/300Counter values are always positive, meaning that the value will never go below zero. Unlike expirevar, the deprecate action must be executed @@ -4802,9 +4810,9 @@ for tracking Basic Authentication attempts. If the client goes over the threshold of more than 25 attempts in 2 minutes, it will DROP subsequent connections.
-SecAction phase:1,initcol:ip=%{REMOTE_ADDR},nolog -SecRule ARGS:login "!^$" "nolog,phase:1,setvar:ip.auth_attempt=+1,deprecatevar:ip.auth_attempt=20/120" -SecRule IP:AUTH_ATTEMPT "@gt 25" "log,drop,phase:1,msg:'Possible Brute Force Attack'" +SecAction phase:1,id:109,initcol:ip=%{REMOTE_ADDR},nolog +SecRule ARGS:login "!^$" "nolog,phase:1,id:110,setvar:ip.auth_attempt=+1,deprecatevar:ip.auth_attempt=20/120" +SecRule IP:AUTH_ATTEMPT "@gt 25" "log,drop,phase:1,id:111,msg:'Possible Brute Force Attack'"
Example:
# Run external program on rule match -SecRule REQUEST_URI "^/cgi-bin/script\.pl" "phase:2,t:none,t:lowercase,t:normalizePath,block,\ exec:/usr/local/apache/bin/test.sh" +SecRule REQUEST_URI "^/cgi-bin/script\.pl" "phase:2,id:112,t:none,t:lowercase,t:normalizePath,block,\ exec:/usr/local/apache/bin/test.sh" # Run Lua script on rule match -SecRule ARGS:p attack "phase:2,block,exec:/usr/local/apache/conf/exec.lua" +SecRule ARGS:p attack "phase:2,id:113,block,exec:/usr/local/apache/conf/exec.lua"
The exec action is executed independently from any disruptive actions specified. External scripts will always be called with no parameters. @@ -4848,8 +4856,8 @@ the given time period (in seconds).
Action Group: Non-disruptive
Example:
-SecRule REQUEST_COOKIES:JSESSIONID "!^$" "nolog,phase:1,pass,setsid:%{REQUEST_COOKIES:JSESSIONID}" -SecRule REQUEST_URI "^/cgi-bin/script\.pl" "phase:2,t:none,t:lowercase,t:normalisePath,log,allow,setvar:session.suspicious=1,expirevar:session.suspicious=3600,phase:1" +SecRule REQUEST_COOKIES:JSESSIONID "!^$" "nolog,phase:1,id:114,pass,setsid:%{REQUEST_COOKIES:JSESSIONID}" +SecRule REQUEST_URI "^/cgi-bin/script\.pl" "phase:2,id:115,t:none,t:lowercase,t:normalisePath,log,allow,setvar:session.suspicious=1,expirevar:session.suspicious=3600,phase:1"You should use the expirevar actions at the same time that you use setvar actions in order to keep the indented expiration time. If they @@ -4908,7 +4916,7 @@ initcol
Example: The following example initiates IP address tracking, which is best done in phase 1:
-SecAction phase:1,nolog,pass,initcol:ip=%{REMOTE_ADDR} +SecAction phase:1,id:116,nolog,pass,initcol:ip=%{REMOTE_ADDR}Collections are loaded into memory on-demand, when the initcol action is executed. A collection will be persisted only if a change was made @@ -4921,7 +4929,7 @@ needs to be logged.
Action Group: Non-disruptive
Example:
-SecAction phase:1,pass,initcol:ip=%{REMOTE_ADDR},log +SecAction phase:1,id:117,pass,initcol:ip=%{REMOTE_ADDR},logThis action will log matches to the Apache error log file and the ModSecurity audit log. @@ -4933,7 +4941,7 @@ message.
Action Group: Non-disruptive
Example:
-SecRule ARGS:p "@rx <script>" "phase:2,log,pass,logdata:%{MATCHED_VAR}" +SecRule ARGS:p "@rx <script>" "phase:2,id:118,log,pass,logdata:%{MATCHED_VAR}"The logdata information appears in the error and/or audit log files. Macro expansion is performed, so you may use variable names such @@ -4975,7 +4983,7 @@ anti-evasion transformation is performed.
Action Group: Non-disruptive
Example:
-SecRule ARGS "attack" "phase1,log,deny,t:removeNulls,t:lowercase,multiMatch" +SecRule ARGS "attack" "phase1,log,deny,id:119,t:removeNulls,t:lowercase,multiMatch"Normally, variables are inspected only once per rule, and only after all transformation functions have been completed. With multiMatch, @@ -4990,7 +4998,7 @@ should be logged to the audit log.
Action Group: Non-disruptive
Example:
-SecRule REQUEST_HEADERS:User-Agent "Test" allow,noauditlog +SecRule REQUEST_HEADERS:User-Agent "Test" allow,noauditlog,id:120If the SecAuditEngine is set to On, all of the transactions will be logged. If it is set to RelevantOnly, then you can control the logging @@ -5007,7 +5015,7 @@ error and audit logs.
Action Group: Non-disruptive
Example:
-SecRule REQUEST_HEADERS:User-Agent "Test" allow,nolog +SecRule REQUEST_HEADERS:User-Agent "Test" allow,nolog,id:121Although nolog implies noauditlog, you can override the former by using nolog,auditlog. @@ -5018,7 +5026,7 @@ of a successful match.
Action Group: Disruptive
Example:
-SecRule REQUEST_HEADERS:User-Agent "Test" "log,pass" +SecRule REQUEST_HEADERS:User-Agent "Test" "log,pass,id:122"When using pass with a SecRule with multiple targets, all variables will be inspected and all non-disruptive actions trigger for every @@ -5026,10 +5034,10 @@ match. In the following example, the TX.test variable will be incremented once for every request parameter:
# Set TX.test to zero -SecAction "phase:2,nolog,pass,setvar:TX.test=0" +SecAction "phase:2,nolog,pass,setvar:TX.test=0,id:123" # Increment TX.test for every request parameter -SecRule ARGS "test" "phase:2,log,pass,setvar:TX.test=+1" +SecRule ARGS "test" "phase:2,log,pass,setvar:TX.test=+1,id:124"pause
Description: Pauses transaction processing for the specified @@ -5038,7 +5046,7 @@ supports macro expansion.
Action Group: Disruptive
Example:
-SecRule REQUEST_HEADERS:User-Agent "Test" "log,pause:5000" +SecRule REQUEST_HEADERS:User-Agent "Test" "log,pause:5000,id:125"
Example:
# Initialize IP address tracking in phase 1 -SecAction phase:1,nolog,pass,initcol:IP=%{REMOTE_ADDR} +SecAction phase:1,nolog,pass,id:126,initcol:IP=%{REMOTE_ADDR}
Starting in ModSecurity version v2.7 there are aliases for some phase numbers: @@ -5066,7 +5074,7 @@ SecAction phase:1,nolog,pass,initcol:IP=%{REMOTE_ADDR}
Example:
-SecRule REQUEST_HEADERS:User-Agent "Test" "phase:request,log,deny" +SecRule REQUEST_HEADERS:User-Agent "Test" "phase:request,log,deny,id:127"
Processing Phases: 3 and 4.
Example:
-SecRule RESPONSE_CONTENT_TYPE ^text/html \ "phase:3,nolog,pass,prepend:'Header<br>'" +SecRule RESPONSE_CONTENT_TYPE ^text/html \ "phase:3,nolog,pass,id:128,prepend:'Header<br>'"
Action Group: Disruptive
Example:
-SecRule REQUEST_HEADERS:User-Agent "Test" log,proxy:http://honeypothost/ +SecRule REQUEST_HEADERS:User-Agent "Test" log,id:129,proxy:http://honeypothost/For this action to work, mod_proxy must also be installed. This action is useful if you would like to proxy matching requests onto a @@ -5114,7 +5122,7 @@ redirect
Action Group: Disruptive
Example:
-SecRule REQUEST_HEADERS:User-Agent "Test" "phase:1,log,redirect:http://www.example.com/failed.html" +SecRule REQUEST_HEADERS:User-Agent "Test" "phase:1,id:130,log,redirect:http://www.example.com/failed.html"If the status action is present on the same rule, and its value can be used for a redirection (i.e., is one of the following: 301, 302, 303, @@ -5144,7 +5152,7 @@ replaced with an asterisk.
Example:
# Never log passwords -SecAction "nolog,phase:2,sanitiseArg:password,sanitiseArg:newPassword,sanitiseArg:oldPassword" +SecAction "nolog,phase:2,id:131,sanitiseArg:password,sanitiseArg:newPassword,sanitiseArg:oldPassword"
SecRule ARGS_NAMES password nolog,pass,sanitiseMatched +SecRule ARGS_NAMES password nolog,pass,id:132,sanitiseMatched
# Detect credit card numbers in parameters and # prevent them from being logged to audit log -SecRule ARGS "@verifyCC \d{13,16}" "phase:2,nolog,capture,pass,msg:'Potential credit card number in request',sanitiseMatchedBytes" -SecRule RESPONSE_BODY "@verifyCC \d{13,16}" "phase:4,t:none,log,capture,block,msg:'Potential credit card number is response body',sanitiseMatchedBytes:0/4" +SecRule ARGS "@verifyCC \d{13,16}" "phase:2,id:133,nolog,capture,pass,msg:'Potential credit card number in request',sanitiseMatchedBytes" +SecRule RESPONSE_BODY "@verifyCC \d{13,16}" "phase:4,id:134,t:none,log,capture,block,msg:'Potential credit card number is response body',sanitiseMatchedBytes:0/4"
Example: This will sanitise the data in the Authorization header.
-SecAction "phase:1,nolog,pass,sanitiseRequestHeader:Authorization" +SecAction "phase:1,nolog,pass,id:135,sanitiseRequestHeader:Authorization"
Example: This will sanitise the Set-Cookie data sent to the client.
-SecAction "phase:3,nolog,pass,sanitiseResponseHeader:Set-Cookie" +SecAction "phase:3,nolog,pass,id:136,sanitiseResponseHeader:Set-Cookie"
Action Group: Non-disruptive
Example:
-SecRule ARGS:username ".*" "phase:2,t:none,pass,nolog,noauditlog,capture,setvar:session.username=%{TX.0},setuid:%{TX.0}" +SecRule ARGS:username ".*" "phase:2,id:137,t:none,pass,nolog,noauditlog,capture,setvar:session.username=%{TX.0},setuid:%{TX.0}"After initialization takes place, the variable USERID will be available for use in the subsequent rules. This action understands @@ -5292,7 +5300,7 @@ SESSION collection using the session token provided as parameter.
Example:
# Initialise session variables using the session cookie value -SecRule REQUEST_COOKIES:PHPSESSID !^$ "chain,nolog,pass,setsid:%{REQUEST_COOKIES.PHPSESSID}" +SecRule REQUEST_COOKIES:PHPSESSID !^$ "nolog,pass,id:138,setsid:%{REQUEST_COOKIES.PHPSESSID}"Note
After the initialization takes place, the variable SESSIONID will @@ -5306,8 +5314,8 @@ variables that can be accessed by Apache.
Action Group: Non-disruptive
Examples:
-SecRule RESPONSE_HEADERS:/Set-Cookie2?/ "(?i:(j?sessionid|(php)?sessid|(asp|jserv|jw)?session[-_]?(id)?|cf(id|token)|sid))" "phase:3,t:none,pass,nolog,setvar:tx.sessionid=%{matched_var}" -SecRule TX:SESSIONID "!(?i:\;? ?httponly;?)" "phase:3,t:none,setenv:httponly_cookie=%{matched_var},pass,log,auditlog,msg:'AppDefect: Missing HttpOnly Cookie Flag.'" +SecRule RESPONSE_HEADERS:/Set-Cookie2?/ "(?i:(j?sessionid|(php)?sessid|(asp|jserv|jw)?session[-_]?(id)?|cf(id|token)|sid))" "phase:3,t:none,pass,id:139,nolog,setvar:tx.sessionid=%{matched_var}" +SecRule TX:SESSIONID "!(?i:\;? ?httponly;?)" "phase:3,id:140,t:none,setenv:httponly_cookie=%{matched_var},pass,log,auditlog,msg:'AppDefect: Missing HttpOnly Cookie Flag.'" Header set Set-Cookie "%{httponly_cookie}e; HTTPOnly" env=httponly_cookie@@ -5343,10 +5351,10 @@ execute when an individual rule matches and not the entire chain.Example:
# Require Accept header, but not from access from the localhost -SecRule REMOTE_ADDR "^127\.0\.0\.1$" "phase:1,skip:1" +SecRule REMOTE_ADDR "^127\.0\.0\.1$" "phase:1,skip:1,id:141" # This rule will be skipped over when REMOTE_ADDR is 127.0.0.1 -SecRule &REQUEST_HEADERS:Accept "@eq 0" "phase:1,deny,msg:'Request Missing an Accept Header'" +SecRule &REQUEST_HEADERS:Accept "@eq 0" "phase:1,id:142,deny,msg:'Request Missing an Accept Header'"The skip action works only within the current processing phase and not necessarily in the order in which the rules appear in the @@ -5364,10 +5372,10 @@ match, resuming rule execution with the first rule that follows the rule the skip example, but using skipAfter:
# Require Accept header, but not from access from the localhost -SecRule REMOTE_ADDR "^127\.0\.0\.1$" "phase:1,skipAfter:IGNORE_LOCALHOST" +SecRule REMOTE_ADDR "^127\.0\.0\.1$" "phase:1,id:143,skipAfter:IGNORE_LOCALHOST" # This rule will be skipped over when REMOTE_ADDR is 127.0.0.1 -SecRule &REQUEST_HEADERS:Accept "@eq 0" "phase:1,deny,msg:'Request Missing an Accept Header'" +SecRule &REQUEST_HEADERS:Accept "@eq 0" "phase:1,deny,id:144,msg:'Request Missing an Accept Header'" SecMarker IGNORE_LOCALHOSTExample from the OWASP ModSecurity CRS: @@ -5399,7 +5407,7 @@ actions deny and redirect.
Example:
# Deny with status 403 -SecDefaultAction "phase:1,log,deny,status:403" +SecDefaultAction "phase:1,log,deny,id:145,status:403"Status actions defined in Apache scope locations (such as Directory, Location, etc...) may be superseded by phase:1 action settings. The @@ -5415,7 +5423,7 @@ rule before matching.
Action Group: Non-disruptive
Example:
-SecRule ARGS "(asfunction|javascript|vbscript|data|mocha|livescript):" "t:none,t:htmlEntityDecode,t:lowercase,t:removeNulls,t:removeWhitespace" +SecRule ARGS "(asfunction|javascript|vbscript|data|mocha|livescript):" "id:146,t:none,t:htmlEntityDecode,t:lowercase,t:removeNulls,t:removeWhitespace"Any transformation functions that you specify in a SecRule will be added to the previous ones specified in SecDefaultAction. It is @@ -5453,9 +5461,9 @@ in the execution of XPath expressions.
Action Group: Data
Example:
-SecRule REQUEST_HEADERS:Content-Type "text/xml" "phase:1,pass,ctl:requestBodyProcessor=XML,ctl:requestBodyAccess=On, \ +SecRule REQUEST_HEADERS:Content-Type "text/xml" "phase:1,id:147,pass,ctl:requestBodyProcessor=XML,ctl:requestBodyAccess=On, \ xmlns:xsd="http://www.w3.org/2001/XMLSchema" -SecRule XML:/soap:Envelope/soap:Body/q1:getInput/id() "123" phase:2,deny +SecRule XML:/soap:Envelope/soap:Body/q1:getInput/id() "123" phase:2,deny,id:148Operators
@@ -5470,7 +5478,8 @@ parameter string before comparison.Example:
# Detect request line that does not begin with "GET" -SecRule REQUEST_LINE "!@beginsWith GET" +SecRule REQUEST_LINE "!@beginsWith GET" "id:149" +contains
@@ -5480,7 +5489,7 @@ string before comparison.Example:
# Detect ".php" anywhere in the request line -SecRule REQUEST_LINE "@contains .php" +SecRule REQUEST_LINE "@contains .php" "id:150"containsWord
@@ -5490,7 +5499,7 @@ boundaries) is found anywhere in the input. Macro expansion is performedExample:
# Detect "select" anywhere in ARGS -SecRule ARGS "@containsWord select" +SecRule ARGS "@containsWord select" "id:151"Would match on -
-1 union select @@ -5508,7 +5517,7 @@ string before comparison.Example:
# Detect request line that does not end with "HTTP/1.1" -SecRule REQUEST_LINE "!@endsWith HTTP/1.1" +SecRule REQUEST_LINE "!@endsWith HTTP/1.1" "id:152"eq
Description: Performs numerical comparison and returns true if @@ -5517,7 +5526,7 @@ performed on the parameter string before comparison.
Example:
# Detect exactly 15 request headers -SecRule &REQUEST_HEADERS_NAMES "@eq 15" +SecRule &REQUEST_HEADERS_NAMES "@eq 15" "id:153"ge
Description: Performs numerical comparison and returns true if @@ -5526,7 +5535,7 @@ Macro expansion is performed on the parameter string before comparison.
Example:
# Detect 15 or more request headers -SecRule &REQUEST_HEADERS_NAMES "@ge 15" +SecRule &REQUEST_HEADERS_NAMES "@ge 15" "id:154"geoLookup
@@ -5544,10 +5553,10 @@ database is), the following example demonstrates how best to do it: SecGeoLookupDb /path/to/GeoLiteCity.dat ... # Lookup IP address -SecRule REMOTE_ADDR "@geoLookup" "phase:1,nolog,pass" +SecRule REMOTE_ADDR "@geoLookup" "phase:1,id:155,nolog,pass" # Block IP address for which geolocation failed - SecRule &GEO "@eq 0" "phase:1,deny,msg:'Failed to lookup IP'" + SecRule &GEO "@eq 0" "phase:1,id:156,deny,msg:'Failed to lookup IP'"See the GEO variable for an example and more information on various fields available. @@ -5570,7 +5579,7 @@ it: SecGsbLookupDb /path/to/GsbMalware.dat ... # Check response bodies for malicious links -SecRule RESPONSE_BODY "@gsbLookup =\"https?\:\/\/(.*?)\"" "phase:4,capture,log,block,msg:'Bad url detected in RESPONSE_BODY (Google Safe Browsing Check)',logdata:'http://www.google.com/safebrowsing/diagnostic?site=%{tx.0}'" +SecRule RESPONSE_BODY "@gsbLookup =\"https?\:\/\/(.*?)\"" "phase:4,id:157,capture,log,block,msg:'Bad url detected in RESPONSE_BODY (Google Safe Browsing Check)',logdata:'http://www.google.com/safebrowsing/diagnostic?site=%{tx.0}'"
gt
Description: Performs numerical comparison and returns true if @@ -5579,7 +5588,7 @@ SecRule RESPONSE_BODY "@gsbLookup =\"https?\:\/\/(.*?)\"" "phase:4,capture,log,b
Example:
# Detect more than 15 headers in a request -SecRule &REQUEST_HEADERS_NAMES "@gt 15" +SecRule &REQUEST_HEADERS_NAMES "@gt 15" "id:158"inspectFile
@@ -5652,12 +5661,12 @@ print "$output\n";Example: Using the runav.pl script:
# Execute external program to validate uploaded files -SecRule FILES_TMPNAMES "@inspectFile /path/to/util/runav.pl" +SecRule FILES_TMPNAMES "@inspectFile /path/to/util/runav.pl" "id:159"Example of using Lua script (placed in the same directory as the configuration file):
-SecRule FILES_TMPNANMES "@inspectFile inspect.lua" +SecRule FILES_TMPNANMES "@inspectFile inspect.lua" "id:160"The contents of inspect.lua:
@@ -5694,11 +5703,11 @@ ipMatchExamples:
Individual Address:
-SecRule REMOTE_ADDR "@ipMatch 192.168.1.100" +SecRule REMOTE_ADDR "@ipMatch 192.168.1.100" "id:161"Multiple Addresses w/network block:
-SecRule REMOTE_ADDR "@ipMatch 192.168.1.100,192.168.1.50,10.10.50.0/24" +SecRule REMOTE_ADDR "@ipMatch 192.168.1.100,192.168.1.50,10.10.50.0/24" "id:162"ipMatchF
@@ -5717,7 +5726,7 @@ class="mw-headline"> ipMatchFromFileExamples:
-SecRule REMOTE_ADDR "@ipMatch ips.txt" +SecRule REMOTE_ADDR "@ipMatch ips.txt" "id:163"The file ips.txt may contain:
@@ -5732,7 +5741,7 @@ expansion is performed on the parameter string before comparison.Example:
# Detect 15 or fewer headers in a request -SecRule &REQUEST_HEADERS_NAMES "@le 15" +SecRule &REQUEST_HEADERS_NAMES "@le 15" "id:164"lt
Description: Performs numerical comparison and returns true if @@ -5741,7 +5750,7 @@ SecRule &REQUEST_HEADERS_NAMES "@le 15"
Example:
# Detect fewer than 15 headers in a request -SecRule &REQUEST_HEADERS_NAMES "@lt 15" +SecRule &REQUEST_HEADERS_NAMES "@lt 15" "id:165"pm
Description: Performs a case-insensitive match of the provided @@ -5753,7 +5762,7 @@ expression.
Example:
# Detect suspicious client by looking at the user agent identification -SecRule REQUEST_HEADERS:User-Agent "@pm WebZIP WebCopier Webster WebStripper ... SiteSnagger ProWebWalker CheeseBot" +SecRule REQUEST_HEADERS:User-Agent "@pm WebZIP WebCopier Webster WebStripper ... SiteSnagger ProWebWalker CheeseBot" "id:166"
# Detect suspicious user agents using the keywords in # the files /path/to/blacklist1 and blacklist2 (the latter # must be placed in the same folder as the configuration file) -SecRule REQUEST_HEADERS:User-Agent "@pm /path/to/blacklist1 blacklist2" +SecRule REQUEST_HEADERS:User-Agent "@pm /path/to/blacklist1 blacklist2" "id:167"
Notes:
@@ -5799,10 +5808,10 @@ own boundaries in phrases. For example, use /1.2.3.4/ instead of just You will find a complete example in the example.# Prepare custom REMOTE_ADDR variable -SecAction "phase:1,nolog,pass,setvar:tx.REMOTE_ADDR=/%{REMOTE_ADDR}/" +SecAction "phase:1,id:168,nolog,pass,setvar:tx.REMOTE_ADDR=/%{REMOTE_ADDR}/" # Check if REMOTE_ADDR is blacklisted -SecRule TX:REMOTE_ADDR "@pmFromFile blacklist.txt" "phase:1,deny,msg:'Blacklisted IP address'" +SecRule TX:REMOTE_ADDR "@pmFromFile blacklist.txt" "phase:1,id:169,deny,msg:'Blacklisted IP address'"
The file blacklist.txt may contain:
@@ -5810,7 +5819,7 @@ SecRule TX:REMOTE_ADDR "@pmFromFile blacklist.txt" "phase:1,deny,msg:'Blackliste # 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}/'" +# SecAction "phase:1,id:170,pass,nolog,setvar:tx.remote_addr='/%{REMOTE_ADDR}/'" /1.2.3.4/ /5.6.7.8/ @@ -5837,7 +5846,7 @@ block list) given as parameter. The parameter can be an IPv4 address or a hostname.Example:
-SecRule REMOTE_ADDR "@rbl sbl-xbl.spamhaus.org" "phase:1,t:none,pass,nolog,auditlog,msg:'RBL Match for SPAM Source',tag:'AUTOMATION/MALICIOUS',severity:'2',setvar:'tx.msg=%{rule.msg}',setvar:tx.automation_score=+%{tx.warning_anomaly_score},setvar:tx.anomaly_score=+%{tx.warning_anomaly_score}, \ +SecRule REMOTE_ADDR "@rbl sbl-xbl.spamhaus.org" "phase:1,id:171,t:none,pass,nolog,auditlog,msg:'RBL Match for SPAM Source',tag:'AUTOMATION/MALICIOUS',severity:'2',setvar:'tx.msg=%{rule.msg}',setvar:tx.automation_score=+%{tx.warning_anomaly_score},setvar:tx.anomaly_score=+%{tx.warning_anomaly_score}, \ setvar:tx.%{rule.id}-AUTOMATION/MALICIOUS-%{matched_var_name}=%{matched_var},setvar:ip.spammer=1,expirevar:ip.spammer=86400,setvar:ip.previous_rbl_check=1,expirevar:ip.previous_rbl_check=86400,skipAfter:END_RBL_CHECK"
SecStreamOutBodyInspection On -SecRule STREAM_OUTPUT_BODY "@rsub s/<!--.*?-->/ /" "phase:4,t:none,nolog,pass" +SecRule STREAM_OUTPUT_BODY "@rsub s/<!--.*?-->/ /" "phase:4,id:172,t:none,nolog,pass"
Examples:
# Detect Nikto -SecRule REQUEST_HEADERS:User-Agent "@rx nikto" phase:1,t:lowercase +SecRule REQUEST_HEADERS:User-Agent "@rx nikto" phase:1,id:173,t:lowercase # Detect Nikto with a case-insensitive pattern -SecRule REQUEST_HEADERS:User-Agent "@rx (?i)nikto" phase:1,t:none +SecRule REQUEST_HEADERS:User-Agent "@rx (?i)nikto" phase:1,id:174,t:none # Detect Nikto with a case-insensitive pattern -SecRule REQUEST_HEADERS:User-Agent "(?i)nikto" +SecRule REQUEST_HEADERS:User-Agent "(?i)nikto" "id:175"
Regular expressions are handled by the PCRE library Example:
# Detect request parameters "foo" that do not # contain "bar", exactly.
-SecRule ARGS:foo "!@streq bar"
+SecRule ARGS:foo "!@streq bar" "id:176"
Example:
# Detect suspicious client by looking at the user agent identification -SecRule REQUEST_HEADERS:User-Agent "@strmatch WebZIP" +SecRule REQUEST_HEADERS:User-Agent "@strmatch WebZIP" "id:177"
# Enforce very strict byte range for request parameters (only # works for the applications that do not use the languages other # than English). -SecRule ARGS "@validateByteRange 10, 13, 32-126" +SecRule ARGS "@validateByteRange 10, 13, 32-126" "id:178"
The validateByteRange is most useful when used to detect the presence of NUL bytes, which don’t have a legitimate use, but which are often used as an evasion technique.
# Do not allow NUL bytes -SecRule ARGS "@validateByteRange 1-255" +SecRule ARGS "@validateByteRange 1-255" "id:179"
Example:
# Parse the request bodies that contain XML -SecRule REQUEST_HEADERS:Content-Type ^text/xml$ "phase:1,nolog,pass,t:lowercase,ctl:requestBodyProcessor=XML" +SecRule REQUEST_HEADERS:Content-Type ^text/xml$ "phase:1,id:180,nolog,pass,t:lowercase,ctl:requestBodyProcessor=XML" # Validate XML payload against DTD -SecRule XML "@validateDTD /path/to/xml.dtd" "phase:2,deny,msg:'Failed DTD validation'" +SecRule XML "@validateDTD /path/to/xml.dtd" "phase:2,id:181,deny,msg:'Failed DTD validation'"
Example:
# Parse the request bodies that contain XML -SecRule REQUEST_HEADERS:Content-Type ^text/xml$ "phase:1,nolog,pass,t:lowercase,ctl:requestBodyProcessor=XML" +SecRule REQUEST_HEADERS:Content-Type ^text/xml$ "phase:1,id:190,nolog,pass,t:lowercase,ctl:requestBodyProcessor=XML" # Validate XML payload against DTD -SecRule XML "@validateSchema /path/to/xml.xsd" "phase:2,deny,msg:'Failed DTD validation'" +SecRule XML "@validateSchema /path/to/xml.xsd" "phase:2,id:191,deny,msg:'Failed DTD validation'"
Example:
# Validate URL-encoded characters in the request URI -SecRule REQUEST_URI_RAW "@validateUrlEncoding" +SecRule REQUEST_URI_RAW "@validateUrlEncoding" "id:192"
ModSecurity will automatically decode the URL-encoded characters in request parameters, which means that there is little sense in applying @@ -6048,7 +6057,7 @@ class="mw-headline"> validateUtf8Encoding
Example:
# Make sure all request parameters contain only valid UTF-8 -SecRule ARGS "@validateUtf8Encoding" +SecRule ARGS "@validateUtf8Encoding" "id:193"
The @validateUtf8Encoding operator detects the following problems:
@@ -6087,7 +6096,7 @@ minimize false positives.# Detect credit card numbers in parameters and # prevent them from being logged to audit log -SecRule ARGS "@verifyCC \d{13,16}" "phase:2,nolog,pass,msg:'Potential credit card number',sanitiseMatched" +SecRule ARGS "@verifyCC \d{13,16}" "phase:2,id:194,nolog,pass,msg:'Potential credit card number',sanitiseMatched"
# Detect CPF numbers in parameters and # prevent them from being logged to audit log -SecRule ARGS "@verifyCPF /^([0-9]{3}\.){2}[0-9]{3}-[0-9]{2}$/" "phase:2,nolog,pass,msg:'Potential CPF number',sanitiseMatched" +SecRule ARGS "@verifyCPF /^([0-9]{3}\.){2}[0-9]{3}-[0-9]{2}$/" "phase:2,id:195,nolog,pass,msg:'Potential CPF number',sanitiseMatched"
# Detect social security numbers in parameters and # prevent them from being logged to audit log -SecRule ARGS "@verifySSN \d{3}-?\d{2}-?\d{4}" "phase:2,nolog,pass,msg:'Potential social security number',sanitiseMatched" +SecRule ARGS "@verifySSN \d{3}-?\d{2}-?\d{4}" "phase:2,id:196,nolog,pass,msg:'Potential social security number',sanitiseMatched"
Version: 2.6
SSN Format: @@ -6492,7 +6501,7 @@ Template argument size: 0/2097152 bytes Expensive parser function count: 0/100 --> - +
@@ -6602,7 +6611,7 @@ pages href="http://sourceforge.net/apps/mediawiki/mod-security/index.php?title=Reference_Manual&printable=yes&printable=yes" rel="alternate" title="Printable version of this page [alt-shift-p]" accesskey="p">Printable version