diff --git a/src/variables/args.h b/src/variables/args.h index 0a26c92e6..227ce1035 100644 --- a/src/variables/args.h +++ b/src/variables/args.h @@ -30,6 +30,64 @@ class Transaction; namespace Variables { class Args_DictElement : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: ARGS + + \verbatim + ARGS is a collection and can be used on its own (means all arguments + including the POST Payload), with a static parameter (matches arguments + with that name), or with a regular expression (matches all arguments with + name that matches the regular expression). To look at only the query + string or body arguments, see the ARGS_GET and ARGS_POST collections. + + Some variables are actually collections, which are expanded into more + variables at runtime. The following example will examine all request + arguments: + + = 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 "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 "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$ "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 "id:11" + + Note : Using ARGS:p will not result in any invocations against the operator + if argument p does not exist. + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: explicit Args_DictElement(std::string dictElement) : Variable("ARGS" + std::string(":") + std::string(dictElement)), diff --git a/src/variables/args_combined_size.h b/src/variables/args_combined_size.h index 82a46d2a7..9060a0a2c 100644 --- a/src/variables/args_combined_size.h +++ b/src/variables/args_combined_size.h @@ -30,6 +30,30 @@ class Transaction; namespace Variables { class ArgsCombinedSize : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: ARGS_COMBINED_SIZE + + \verbatim + Contains the combined size of all request parameters. Files are excluded + from the calculation. This variable can be useful, for example, to create a + rule to ensure that the total size of the argument data is below a certain + threshold. The following rule detects a request whose para- meters are more + than 2500 bytes long: + + = SecRule ARGS_COMBINED_SIZE "@gt 2500" "id:12" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: ArgsCombinedSize() : Variable("ARGS_COMBINED_SIZE") { } diff --git a/src/variables/args_get.h b/src/variables/args_get.h index 374429ba2..a3c6fd601 100644 --- a/src/variables/args_get.h +++ b/src/variables/args_get.h @@ -30,6 +30,24 @@ class Transaction; namespace Variables { class ArgsGet_DictElement : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: ARGS_GET + + \verbatim + ARGS_GET is similar to ARGS, but contains only query string parameters. + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: explicit ArgsGet_DictElement(std::string dictElement) : Variable("ARGS_GET" + std::string(":") + std::string(dictElement)), diff --git a/src/variables/args_get_names.h b/src/variables/args_get_names.h index 7e43a74fe..102f92b80 100644 --- a/src/variables/args_get_names.h +++ b/src/variables/args_get_names.h @@ -30,6 +30,24 @@ class Transaction; namespace Variables { class ArgsGetNames_DictElement : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: ARGS_GET_NAMES + + \verbatim + ARGS_GET_NAMES is similar to ARGS_NAMES, but contains only the names of query string parameters. + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: explicit ArgsGetNames_DictElement(std::string dictElement) : Variable("ARGS_GET_NAMES" + std::string(":") + diff --git a/src/variables/args_names.h b/src/variables/args_names.h index 1f1640153..9181ef4c7 100644 --- a/src/variables/args_names.h +++ b/src/variables/args_names.h @@ -30,6 +30,30 @@ class Transaction; namespace Variables { class ArgsNames_DictElement : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: ARGS_NAMES + + \verbatim + Contains all request parameter names. You can search for specific parameter + names that you want to inspect. In a positive policy scenario, you can also + whitelist (using an inverted rule with the exclamation mark) only the + authorized argument names. This example rule allows only two argument names: + p and a: + + = SecRule ARGS_NAMES "!^(p|a)$" "id:13" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: explicit ArgsNames_DictElement(std::string dictElement) : Variable("ARGS_NAMES" + std::string(":") + diff --git a/src/variables/args_post.h b/src/variables/args_post.h index 5403264d0..64188f6bd 100644 --- a/src/variables/args_post.h +++ b/src/variables/args_post.h @@ -30,6 +30,25 @@ class Transaction; namespace Variables { class ArgsPost_DictElement : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: ARGS_POST + + \verbatim + ARGS_POST is similar to ARGS, but only contains arguments from the POST + body. + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: explicit ArgsPost_DictElement(std::string dictElement) : Variable("ARGS_POST" + std::string(":") + std::string(dictElement)), diff --git a/src/variables/args_post_names.h b/src/variables/args_post_names.h index 6de81a1b7..4dded6256 100644 --- a/src/variables/args_post_names.h +++ b/src/variables/args_post_names.h @@ -30,6 +30,25 @@ class Transaction; namespace Variables { class ArgsPostNames_DictElement : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: ARGS_POST_NAMES + + \verbatim + ARGS_POST_NAMES is similar to ARGS_NAMES, but contains only the names of + request body parameters. + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: explicit ArgsPostNames_DictElement(std::string dictElement) : Variable("ARGS_POST_NAMES" + std::string(":") + diff --git a/src/variables/auth_type.h b/src/variables/auth_type.h index 90f871207..fa76c70aa 100644 --- a/src/variables/auth_type.h +++ b/src/variables/auth_type.h @@ -30,6 +30,29 @@ class Transaction; namespace Variables { class AuthType : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: AUTH_TYPE + + \verbatim + This variable holds the authentication method used to validate a user, if + any of the methods built into HTTP are used. In a reverse-proxy deployment, + this information will not be available if the authentication is handled in + the backend web server. + + = SecRule AUTH_TYPE "Basic" "id:14" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: AuthType() : Variable("AUTH_TYPE") { } diff --git a/src/variables/duration.h b/src/variables/duration.h index 5ca8ba060..fa0bc5284 100644 --- a/src/variables/duration.h +++ b/src/variables/duration.h @@ -29,6 +29,26 @@ class Transaction; namespace Variables { class Duration : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: DURATION + + \verbatim + Contains the number of milliseconds elapsed since the beginning of the + current transaction. Available starting with 2.6.0. + + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: explicit Duration(std::string _name) : Variable(_name), diff --git a/src/variables/env.h b/src/variables/env.h index c1df6e3ad..b36135689 100644 --- a/src/variables/env.h +++ b/src/variables/env.h @@ -29,6 +29,36 @@ class Transaction; namespace Variables { class Env : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: ENV + + \verbatim + Collection that provides access to environment variables set by ModSecurity + or other server modules. Requires a single parameter to specify the name of + the desired variable. + + = # Set environment variable + = SecRule REQUEST_FILENAME "printenv" "phase:2,id:15,pass,setenv:tag=suspicious" + = + = # Inspect environment variable + = SecRule ENV:tag "suspicious" "id:16" + = + = # Reading an environment variable from other Apache module (mod_ssl) + = SecRule TX:ANOMALY_SCORE "@gt 0" "phase:5,id:16,msg:'%{env.ssl_cipher}'" + + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: explicit Env(std::string _name) : Variable(_name) { } diff --git a/src/variables/files.h b/src/variables/files.h index 397ca0e49..3047dc5ae 100644 --- a/src/variables/files.h +++ b/src/variables/files.h @@ -30,6 +30,28 @@ class Transaction; namespace Variables { class Files_DictElement : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: FILES + + \verbatim + 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$" "id:17" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: explicit Files_DictElement(std::string dictElement) : Variable("FILES" + std::string(":") + diff --git a/src/variables/files_combined_size.h b/src/variables/files_combined_size.h index e3070f571..b78d961d6 100644 --- a/src/variables/files_combined_size.h +++ b/src/variables/files_combined_size.h @@ -30,6 +30,27 @@ class Transaction; namespace Variables { class FilesCombinedSize : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: FILES_COMBINED_SIZE + + \verbatim + 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" "id:18" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: FilesCombinedSize() : Variable("FILES_COMBINED_SIZE") { } diff --git a/src/variables/files_names.h b/src/variables/files_names.h index be498e8a7..6489c4666 100644 --- a/src/variables/files_names.h +++ b/src/variables/files_names.h @@ -30,6 +30,27 @@ class Transaction; namespace Variables { class FilesNames_DictElement : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: FILES_NAMES + + \verbatim + Contains a list of form fields that were used for file upload. Available + only on inspected multipart/form-data requests. + + = SecRule FILES_NAMES "^upfile$" "id:19" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: explicit FilesNames_DictElement(std::string dictElement) : Variable("FILES_NAMES" + std::string(":") + diff --git a/src/variables/files_sizes.h b/src/variables/files_sizes.h index 461da6bcc..b577ae8e3 100644 --- a/src/variables/files_sizes.h +++ b/src/variables/files_sizes.h @@ -30,6 +30,28 @@ class Transaction; namespace Variables { class FilesSizes_DictElement : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: FILES_SIZES + + \verbatim + 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" "id:20" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: explicit FilesSizes_DictElement(std::string dictElement) : Variable("FILES_SIZES" + std::string(":") + diff --git a/src/variables/files_tmp_content.h b/src/variables/files_tmp_content.h index 54adbab62..e1333e08f 100644 --- a/src/variables/files_tmp_content.h +++ b/src/variables/files_tmp_content.h @@ -30,6 +30,29 @@ class Transaction; namespace Variables { class FilesTmpContent_DictElement : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: FILES_TMP_CONTENT + + \verbatim + Contains a key-value set where value is the content of the file which was + uploaded. Useful when used together with @fuzzyHash. + + = SecRule FILES_TMP_CONTENT "@fuzzyHash $ENV{CONF_DIR}/ssdeep.txt 1" "id:192372,log,deny" + + Note: SecUploadKeepFiles should be set to 'On' in order to have this collection filled. + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: explicit FilesTmpContent_DictElement(std::string dictElement) : Variable("FILES_TMP_CONTENT" + std::string(":") + diff --git a/src/variables/files_tmp_names.h b/src/variables/files_tmp_names.h index 515bbd394..4bfc5cf31 100644 --- a/src/variables/files_tmp_names.h +++ b/src/variables/files_tmp_names.h @@ -29,6 +29,28 @@ namespace modsecurity { class Transaction; namespace Variables { class FilesTmpNames_DictElement : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: FILES_TMPNAMES + + \verbatim + Contains a list of temporary files’ names on the disk. Useful when used + together with @inspectFile. Available only on inspected multipart/form-data + requests. + + = SecRule FILES_TMPNAMES "@inspectFile /path/to/inspect_script.pl" "id:21" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: explicit FilesTmpNames_DictElement(std::string dictElement) : Variable("FILES_TMPNAMES" + std::string(":") + diff --git a/src/variables/full_request.h b/src/variables/full_request.h index ad64ad0a4..d42fa94b8 100644 --- a/src/variables/full_request.h +++ b/src/variables/full_request.h @@ -30,6 +30,29 @@ class Transaction; namespace Variables { class FullRequest : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: FULL_REQUEST + + \verbatim + Contains the complete request: Request line, Request headers and Request + body (if any). The last available only if SecRequestBodyAccess was set to + On. Note that all properties of SecRequestBodyAccess will be respected + here, such as: SecRequestBodyLimit. + + = SecRule FULL_REQUEST "User-Agent: ModSecurity Regression Tests" "id:21" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: FullRequest() : Variable("FULL_REQUEST") { } diff --git a/src/variables/full_request_length.h b/src/variables/full_request_length.h index 5d199b1af..dc8b23072 100644 --- a/src/variables/full_request_length.h +++ b/src/variables/full_request_length.h @@ -30,6 +30,26 @@ class Transaction; namespace Variables { class FullRequestLength : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: FULL_REQUEST_LENGTH + + \verbatim + Represents the amount of bytes that FULL_REQUEST may use. + + = SecRule FULL_REQUEST_LENGTH "@eq 205" "id:21" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: FullRequestLength() : Variable("FULL_REQUEST_LENGTH") { } diff --git a/src/variables/geo.h b/src/variables/geo.h index 0ee3e94bf..883ec3a51 100644 --- a/src/variables/geo.h +++ b/src/variables/geo.h @@ -30,6 +30,44 @@ class Transaction; namespace Variables { class Geo_DictElement : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: GEO + + \verbatim + GEO is a collection populated by the results of the last @geoLookup + operator. The collection can be used to match geographical fields + looked from an IP address or hostname. + + Fields: + + - COUNTRY_CODE: Two character country code. EX: US, GB, etc. + - COUNTRY_CODE3: Up to three character country code. + - COUNTRY_NAME: The full country name. + - COUNTRY_CONTINENT: The two character continent that the country is located. EX: EU + - REGION: The two character region. For US, this is state. For Canada, providence, etc. + - CITY: The city name if supported by the database. + - POSTAL_CODE: The postal code if supported by the database. + - LATITUDE: The latitude if supported by the database. + - LONGITUDE: The longitude if supported by the database. + - DMA_CODE: The metropolitan area code if supported by the database. (US only) + - AREA_CODE: The phone system area code. (US only) + + = SecGeoLookupDb /usr/local/geo/data/GeoLiteCity.dat + = SecRule REMOTE_ADDR "@geoLookup" "chain,id:22,drop,msg:'Non-GB IP address'" + = SecRule GEO:COUNTRY_CODE "!@streq GB" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: explicit Geo_DictElement(std::string dictElement) : Variable("GEO" + std::string(":") + diff --git a/src/variables/global.h b/src/variables/global.h index 0d396df62..4397d2ab6 100644 --- a/src/variables/global.h +++ b/src/variables/global.h @@ -32,6 +32,23 @@ namespace Variables { class Global_DictElement : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: GLOBAL + + \verbatim + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: explicit Global_DictElement(std::string dictElement) : Variable("GLOBAL"), diff --git a/src/variables/highest_severity.h b/src/variables/highest_severity.h index 630eb7ea4..d79685764 100644 --- a/src/variables/highest_severity.h +++ b/src/variables/highest_severity.h @@ -29,6 +29,31 @@ class Transaction; namespace Variables { class HighestSeverity : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: HIGHEST_SEVERITY + + \verbatim + This variable holds the highest severity of any rules that have matched so + far. Severities are numeric values and thus can be used with comparison + operators such as @lt, and so on. A value of 255 indicates that no severity + has been set. + + = SecRule HIGHEST_SEVERITY "@le 2" "phase:2,id:23,deny,status:500,msg:'severity %{HIGHEST_SEVERITY}'" + + Note: Higher severities have a lower numeric value. + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: explicit HighestSeverity(std::string _name) : Variable(_name), diff --git a/src/variables/inbound_data_error.h b/src/variables/inbound_data_error.h index 71f4498eb..94d9b4bf3 100644 --- a/src/variables/inbound_data_error.h +++ b/src/variables/inbound_data_error.h @@ -30,6 +30,32 @@ class Transaction; namespace Variables { class InboundDataError : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: INBOUND_DATA_ERROR + + \verbatim + This variable will be set to 1 when the request body size is above the + setting configured by SecRequestBodyLimit directive. Your policies should + always contain a rule to check this variable. Depending on the 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 INBOUND_DATA_ERROR "@eq 1" "phase:1,id:24,t:none,log,pass,msg:'Request Body Larger than SecRequestBodyLimit Setting'" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: InboundDataError() : Variable("INBOUND_DATA_ERROR") { } diff --git a/src/variables/ip.h b/src/variables/ip.h index 92cded8e5..6b83050b6 100644 --- a/src/variables/ip.h +++ b/src/variables/ip.h @@ -32,6 +32,23 @@ namespace Variables { class Ip_DictElement : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: IP + + \verbatim + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: explicit Ip_DictElement(std::string dictElement) : Variable("IP:" + dictElement), diff --git a/src/variables/matched_var.h b/src/variables/matched_var.h index bd4899c75..a5eb2268c 100644 --- a/src/variables/matched_var.h +++ b/src/variables/matched_var.h @@ -30,6 +30,33 @@ class Transaction; namespace Variables { class MatchedVar : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: MATCHED_VAR + + \verbatim + This variable holds the value of the most-recently matched variable. It is + similar to the TX:0, but it is automatically supported by all operators and + there is no need to specify the capture action. + + = SecRule ARGS pattern chain,deny,id:25 + = SecRule MATCHED_VAR "further scrutiny" + + Note: Be aware that this variable holds data for the last operator match. + This means that if there are more than one matches, only the last one will + be populated. Use MATCHED_VARS variable if you want all matches. + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: MatchedVar() : Variable("MATCHED_VAR") { } diff --git a/src/variables/matched_var_name.h b/src/variables/matched_var_name.h index af5b16885..f1f363ead 100644 --- a/src/variables/matched_var_name.h +++ b/src/variables/matched_var_name.h @@ -30,6 +30,31 @@ class Transaction; namespace Variables { class MatchedVarName : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: MATCHED_VAR_NAME + + \verbatim + This variable holds the full name of the variable that was matched against. + + = SecRule ARGS pattern "chain,deny,id:27" + = SecRule MATCHED_VAR_NAME "@eq ARGS:param" + + Note: Be aware that this variable holds data for the last operator match. + This means that if there are more than one matches, only the last one will + be populated. Use MATCHED_VARS_NAMES variable if you want all matches. + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: MatchedVarName() : Variable("MATCHED_VAR_NAME") { } diff --git a/src/variables/matched_vars.h b/src/variables/matched_vars.h index 7f19079be..0af6c6c26 100644 --- a/src/variables/matched_vars.h +++ b/src/variables/matched_vars.h @@ -30,6 +30,28 @@ class Transaction; namespace Variables { class MatchedVars_DictElement : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: MATCHED_VARS + + \verbatim + Similar to MATCHED_VAR except that it is a collection of all matches for + the current operator check. + + = SecRule ARGS pattern "chain,deny,id:26" + = SecRule MATCHED_VARS "@eq ARGS:param" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: explicit MatchedVars_DictElement(std::string dictElement) : Variable("MATCHED_VARS" + std::string(":") + diff --git a/src/variables/matched_vars_names.h b/src/variables/matched_vars_names.h index 604d6e5a1..66044f9e5 100644 --- a/src/variables/matched_vars_names.h +++ b/src/variables/matched_vars_names.h @@ -30,6 +30,28 @@ class Transaction; namespace Variables { class MatchedVarsNames_DictElement : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: MATCHED_VARS_NAMES + + \verbatim + Similar to MATCHED_VAR_NAME except that it is a collection of all matches + for the current operator check. + + = SecRule ARGS pattern "chain,deny,id:28" + = SecRule MATCHED_VARS_NAMES "@eq ARGS:param" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: explicit MatchedVarsNames_DictElement(std::string dictElement) : Variable("MATCHED_VARS_NAMES" + std::string(":") + diff --git a/src/variables/modsec_build.h b/src/variables/modsec_build.h index f5f90de49..d76e1f404 100644 --- a/src/variables/modsec_build.h +++ b/src/variables/modsec_build.h @@ -31,6 +31,29 @@ class Transaction; namespace Variables { class ModsecBuild : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: MODSEC_BUILD + + \verbatim + This variable holds the ModSecurity build number. This variable is 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,id:29" + = SecRule ARGS "@pm some key words" "id:12345,deny,status:500" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: explicit ModsecBuild(std::string _name) : Variable(_name), diff --git a/src/variables/multipart_boundary_quoted.h b/src/variables/multipart_boundary_quoted.h index ec753045a..01e71d831 100644 --- a/src/variables/multipart_boundary_quoted.h +++ b/src/variables/multipart_boundary_quoted.h @@ -30,6 +30,23 @@ class Transaction; namespace Variables { class MultipartBoundaryQuoted : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: MULTIPART_BOUNDARY_QUOTED + + \verbatim + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: MultipartBoundaryQuoted() : Variable("MULTIPART_BOUNDARY_QUOTED") { } diff --git a/src/variables/multipart_boundary_whitespace.h b/src/variables/multipart_boundary_whitespace.h index 1a94b0a1f..f8be2baee 100644 --- a/src/variables/multipart_boundary_whitespace.h +++ b/src/variables/multipart_boundary_whitespace.h @@ -30,6 +30,23 @@ class Transaction; namespace Variables { class MultipartBoundaryWhiteSpace : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: MULTIPART_BOUNDARY_WHITESPACE + + \verbatim + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: MultipartBoundaryWhiteSpace() : Variable("MULTIPART_BOUNDARY_WHITESPACE") { } diff --git a/src/variables/multipart_crlf_lf_lines.h b/src/variables/multipart_crlf_lf_lines.h index 8df96374b..66911aa6c 100644 --- a/src/variables/multipart_crlf_lf_lines.h +++ b/src/variables/multipart_crlf_lf_lines.h @@ -30,6 +30,32 @@ class Transaction; namespace Variables { class MultipartCrlfLFLines : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: MULTIPART_CRLF_LF_LINES + + \verbatim + This flag variable will be set to 1 whenever a multi-part request uses + mixed line terminators. The multipart/form-data RFC requires CRLF sequence + to be used to terminate lines. Since some client implementations use only + LF to terminate lines you might want to allow them to proceed under certain + circumstances (if you want to do this you will need to stop using + MULTIPART_STRICT_ERROR and check each multi-part flag variable + individually, avoiding MULTIPART_LF_LINE). However, mixing CRLF and LF line + terminators is dangerous as it can allow for evasion. Therefore, in such + cases, you will have to add a check for MULTIPART_CRLF_LF_LINES. + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: MultipartCrlfLFLines() : Variable("MULTIPART_CRLF_LF_LINES") { } diff --git a/src/variables/multipart_data_after.h b/src/variables/multipart_data_after.h index 5509b5b98..166ef350c 100644 --- a/src/variables/multipart_data_after.h +++ b/src/variables/multipart_data_after.h @@ -30,6 +30,23 @@ class Transaction; namespace Variables { class MultipartDateAfter : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: MULTIPART_DATA_AFTER + + \verbatim + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: MultipartDateAfter() : Variable("MULTIPART_DATA_AFTER") { } diff --git a/src/variables/multipart_data_before.h b/src/variables/multipart_data_before.h index 1f72511b1..c0b04f9f8 100644 --- a/src/variables/multipart_data_before.h +++ b/src/variables/multipart_data_before.h @@ -30,6 +30,23 @@ class Transaction; namespace Variables { class MultipartDateBefore : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: MULTIPART_DATA_BEFORE + + \verbatim + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: MultipartDateBefore() : Variable("MULTIPART_DATA_BEFORE") { } diff --git a/src/variables/multipart_file_limit_exceeded.h b/src/variables/multipart_file_limit_exceeded.h index bba687d83..0d485d9cf 100644 --- a/src/variables/multipart_file_limit_exceeded.h +++ b/src/variables/multipart_file_limit_exceeded.h @@ -30,6 +30,23 @@ class Transaction; namespace Variables { class MultipartFileLimitExceeded : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: MULTIPART_FILE_LIMIT_EXCEEDED + + \verbatim + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: MultipartFileLimitExceeded() : Variable("MULTIPART_FILE_LIMIT_EXCEEDED") { } diff --git a/src/variables/multipart_file_name.h b/src/variables/multipart_file_name.h index b3bf41ba9..83c2be3f3 100644 --- a/src/variables/multipart_file_name.h +++ b/src/variables/multipart_file_name.h @@ -30,6 +30,24 @@ class Transaction; namespace Variables { class MultiPartFileName_DictElement : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: MULTIPART_FILENAME + + \verbatim + This variable contains the multipart data from field FILENAME. + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: explicit MultiPartFileName_DictElement(std::string dictElement) : Variable("MULTIPART_FILENAME" + std::string(":") + diff --git a/src/variables/multipart_header_folding.h b/src/variables/multipart_header_folding.h index c21a3cd25..9915e5c62 100644 --- a/src/variables/multipart_header_folding.h +++ b/src/variables/multipart_header_folding.h @@ -30,6 +30,23 @@ class Transaction; namespace Variables { class MultipartHeaderFolding : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: MULTIPART_HEADER_FOLDING + + \verbatim + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: MultipartHeaderFolding() : Variable("MULTIPART_HEADER_FOLDING") { } diff --git a/src/variables/multipart_invalid_header_folding.h b/src/variables/multipart_invalid_header_folding.h index 098f7df1d..e5302603b 100644 --- a/src/variables/multipart_invalid_header_folding.h +++ b/src/variables/multipart_invalid_header_folding.h @@ -30,6 +30,23 @@ class Transaction; namespace Variables { class MultipartInvalidHeaderFolding : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: MULTIPART_INVALID_HEADER_FOLDING + + \verbatim + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: MultipartInvalidHeaderFolding() : Variable("MULTIPART_INVALID_HEADER_FOLDING") { } diff --git a/src/variables/multipart_invalid_part.h b/src/variables/multipart_invalid_part.h index fa40724aa..0823f1933 100644 --- a/src/variables/multipart_invalid_part.h +++ b/src/variables/multipart_invalid_part.h @@ -30,6 +30,23 @@ class Transaction; namespace Variables { class MultipartInvalidPart : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: MULTIPART_INVALID_PART + + \verbatim + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: MultipartInvalidPart() : Variable("MULTIPART_INVALID_PART") { } diff --git a/src/variables/multipart_invalid_quoting.h b/src/variables/multipart_invalid_quoting.h index 8ef5f471a..fe617bd90 100644 --- a/src/variables/multipart_invalid_quoting.h +++ b/src/variables/multipart_invalid_quoting.h @@ -30,6 +30,23 @@ class Transaction; namespace Variables { class MultipartInvalidQuoting : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: MULTIPART_INVALID_QUOTING + + \verbatim + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: MultipartInvalidQuoting() : Variable("MULTIPART_INVALID_QUOTING") { } diff --git a/src/variables/multipart_lf_line.h b/src/variables/multipart_lf_line.h index 20edd679c..1944d441f 100644 --- a/src/variables/multipart_lf_line.h +++ b/src/variables/multipart_lf_line.h @@ -30,6 +30,23 @@ class Transaction; namespace Variables { class MultipartLFLine : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: MULTIPART_LF_LINE + + \verbatim + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: MultipartLFLine() : Variable("MULTIPART_LF_LINE") { } diff --git a/src/variables/multipart_missing_semicolon.h b/src/variables/multipart_missing_semicolon.h index dc298ac66..e6a4bb5e9 100644 --- a/src/variables/multipart_missing_semicolon.h +++ b/src/variables/multipart_missing_semicolon.h @@ -30,6 +30,23 @@ class Transaction; namespace Variables { class MultipartMissingSemicolon : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: MULTIPART_MISSING_SEMICOLON + + \verbatim + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: MultipartMissingSemicolon() : Variable("MULTIPART_MISSING_SEMICOLON") { } diff --git a/src/variables/multipart_name.h b/src/variables/multipart_name.h index e1edfaacd..00d7534b1 100644 --- a/src/variables/multipart_name.h +++ b/src/variables/multipart_name.h @@ -30,6 +30,24 @@ class Transaction; namespace Variables { class MultiPartName_DictElement : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: MULTIPART_NAME + + \verbatim + This variable contains the multipart data from field NAME. + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: explicit MultiPartName_DictElement(std::string dictElement) : Variable("MULTIPART_NAME" + std::string(":") + diff --git a/src/variables/multipart_strict_error.h b/src/variables/multipart_strict_error.h index 627c68552..aadf2e3bf 100644 --- a/src/variables/multipart_strict_error.h +++ b/src/variables/multipart_strict_error.h @@ -30,6 +30,47 @@ class Transaction; namespace Variables { class MultipartStrictError : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: MULTIPART_STRICT_ERROR + + \verbatim + MULTIPART_STRICT_ERROR will be set to 1 when any of the following variables + is also set to 1: REQBODY_PROCESSOR_ERROR, MULTIPART_BOUNDARY_QUOTED, + MULTIPART_BOUNDARY_WHITESPACE, MULTIPART_DATA_BEFORE, MULTIPART_DATA_AFTER, + MULTIPART_HEADER_FOLDING, MULTIPART_LF_LINE, MULTIPART_MISSING_SEMICOLON + MULTIPART_INVALID_QUOTING MULTIPART_INVALID_HEADER_FOLDING + MULTIPART_FILE_LIMIT_EXCEEDED. Each of these variables covers one unusual + (although sometimes legal) aspect of the request body in + multipart/form-data format. Your policies should always contain a rule to + check either this variable (easier) or one or more individual variables (if + you know exactly what you want to accomplish). Depending on the 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 MULTIPART_STRICT_ERROR "!@eq 0" "phase:2,id:30,t:none,log,deny,msg:'Multipart request body failed strict validation: PE %{REQBODY_PROCESSOR_ERROR}, BQ %{MULTIPART_BOUNDARY_QUOTED}, BW %{MULTIPART_BOUNDARY_WHITESPACE}, DB %{MULTIPART_DATA_BEFORE}, DA %{MULTIPART_DATA_AFTER}, HF %{MULTIPART_HEADER_FOLDING}, \ +LF %{MULTIPART_LF_LINE}, SM %{MULTIPART_MISSING_SEMICOLON}, IQ %{MULTIPART_INVALID_QUOTING}, IQ %{MULTIPART_INVALID_HEADER_FOLDING}, FE %{MULTIPART_FILE_LIMIT_EXCEEDED}'" + + The multipart/form-data parser was upgraded in ModSecurity v2.1.3 to + actively look for signs of evasion. Many variables (as listed above) + were added to expose various facts discovered during the parsing process. + The MULTIPART_STRICT_ERROR variable is handy to check on all abnormalities + at once. The individual variables allow detection to be fine-tuned + according to your circumstances in order to reduce the number of false + positives. + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: MultipartStrictError() : Variable("MULTIPART_STRICT_ERROR") { } diff --git a/src/variables/multipart_unmatched_boundary.h b/src/variables/multipart_unmatched_boundary.h index 5d0c307bd..8b8214331 100644 --- a/src/variables/multipart_unmatched_boundary.h +++ b/src/variables/multipart_unmatched_boundary.h @@ -30,6 +30,34 @@ class Transaction; namespace Variables { class MultipartUnmatchedBoundary : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: MULTIPART_UNMATCHED_BOUNDARY + + \verbatim + Set to 1 when, during the parsing phase of a multipart/request-body, + ModSecurity encounters what feels like a boundary but it is not. Such an + event may occur when evasion of ModSecurity is attempted. + + The best way to use this variable is as in the example below: + + = SecRule MULTIPART_UNMATCHED_BOUNDARY "!@eq 0" \ +"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. + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: MultipartUnmatchedBoundary() : Variable("MULTIPART_UNMATCHED_BOUNDARY") { } diff --git a/src/variables/outbound_data_error.h b/src/variables/outbound_data_error.h index a07e9a85c..c20eaff46 100644 --- a/src/variables/outbound_data_error.h +++ b/src/variables/outbound_data_error.h @@ -30,6 +30,31 @@ class Transaction; namespace Variables { class OutboundDataError : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: OUTBOUND_DATA_ERROR + + \verbatim + This variable will be set to 1 when the response body size is above the + setting configured by SecResponseBodyLimit directive. Your policies should + always contain a rule to check this variable. Depending on the 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,id:32,t:none,log,pass,msg:'Response Body Larger than SecResponseBodyLimit Setting'" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: OutboundDataError() : Variable("OUTBOUND_DATA_ERROR") { } diff --git a/src/variables/path_info.h b/src/variables/path_info.h index d07ba663b..1f765629f 100644 --- a/src/variables/path_info.h +++ b/src/variables/path_info.h @@ -30,6 +30,28 @@ class Transaction; namespace Variables { class PathInfo : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: PATH_INFO + + \verbatim + 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)" "id:33" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: PathInfo() : Variable("PATH_INFO") { } diff --git a/src/variables/query_string.h b/src/variables/query_string.h index ff4be2924..6f33cb7f0 100644 --- a/src/variables/query_string.h +++ b/src/variables/query_string.h @@ -30,6 +30,27 @@ class Transaction; namespace Variables { class QueryString : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: QUERY_STRING + + \verbatim + Contains 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" "id:34" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: QueryString() : Variable("QUERY_STRING") { } diff --git a/src/variables/remote_addr.h b/src/variables/remote_addr.h index 6d71d8bdd..dcfa3de60 100644 --- a/src/variables/remote_addr.h +++ b/src/variables/remote_addr.h @@ -30,6 +30,26 @@ class Transaction; namespace Variables { class RemoteAddr : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: REMOTE_ADDR + + \verbatim + This variable holds the IP address of the remote client. + + = SecRule REMOTE_ADDR "@ipMatch 192.168.1.101" "id:35" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: RemoteAddr() : Variable("REMOTE_ADDR") { } diff --git a/src/variables/remote_host.h b/src/variables/remote_host.h index 316d36fa3..fc714adc1 100644 --- a/src/variables/remote_host.h +++ b/src/variables/remote_host.h @@ -30,6 +30,31 @@ class Transaction; namespace Variables { class RemoteHost : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: REMOTE_HOST + + \verbatim + If the Apache directive HostnameLookups is set to On, then this variable + will hold the remote hostname resolved through DNS. If the 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$" "id:36" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: RemoteHost() : Variable("REMOTE_HOST") { } diff --git a/src/variables/remote_port.h b/src/variables/remote_port.h index 9b9bf5ded..e4a7a861f 100644 --- a/src/variables/remote_port.h +++ b/src/variables/remote_port.h @@ -30,6 +30,30 @@ class Transaction; namespace Variables { class RemotePort : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: REMOTE_PORT + + \verbatim + This variable holds information on the source port that the client 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" "id:37" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: RemotePort() : Variable("REMOTE_PORT") { } diff --git a/src/variables/remote_user.h b/src/variables/remote_user.h index 7106fc483..b76e4843b 100644 --- a/src/variables/remote_user.h +++ b/src/variables/remote_user.h @@ -31,6 +31,31 @@ namespace Variables { class RemoteUser : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: REMOTE_USER + + \verbatim + 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 "@streq admin" "id:38" + + Note: In a reverse-proxy deployment, this information will not be available + if the authentication is handled in the backend web server. + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: explicit RemoteUser(std::string _name) : Variable(_name), diff --git a/src/variables/reqbody_error.h b/src/variables/reqbody_error.h index 662410142..544fa7e29 100644 --- a/src/variables/reqbody_error.h +++ b/src/variables/reqbody_error.h @@ -30,6 +30,38 @@ class Transaction; namespace Variables { class ReqbodyError : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: REQBODY_ERROR + + \verbatim + Contains the status of the request body processor used for request body + parsing. The values can be 0 (no error) or 1 (error). This variable will be + set by request body processors (typically the multipart/request-data + parser, JSON or the XML parser) when they fail to do their work. + + = SecRule REQBODY_ERROR "@eq 1" deny,phase:2,id:39 + + Note: Your policies must have a rule to check for request body processor + errors at the very beginning of phase 2. Failure to do so will leave the + door open for impedance mismatch attacks. It is possible, for example, that + a payload that cannot be parsed by ModSecurity can be successfully parsed + by more tolerant parser operating in the application. If your policy + dictates blocking, then you should reject the request if error is detected. + When operating in detection-only mode, your rule should alert with high + severity when request body processing fails. + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: ReqbodyError() : Variable("REQBODY_ERROR") { } diff --git a/src/variables/reqbody_error_msg.h b/src/variables/reqbody_error_msg.h index d6368571c..bbbdcba57 100644 --- a/src/variables/reqbody_error_msg.h +++ b/src/variables/reqbody_error_msg.h @@ -30,6 +30,27 @@ class Transaction; namespace Variables { class ReqbodyErrorMsg : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: REQBODY_ERROR_MSG + + \verbatim + 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" "id:40" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: ReqbodyErrorMsg() : Variable("REQBODY_ERROR_MSG") { } diff --git a/src/variables/reqbody_processor.h b/src/variables/reqbody_processor.h index 05241a6d1..7da973904 100644 --- a/src/variables/reqbody_processor.h +++ b/src/variables/reqbody_processor.h @@ -30,6 +30,28 @@ class Transaction; namespace Variables { class ReqbodyProcessor : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: REQBODY_PROCESSOR + + \verbatim + Contains the name of the currently used request body processor. The + possible values are URLENCODED, MULTIPART, and XML. + + = SecRule REQBODY_PROCESSOR "^XML$ chain,id:41" + = SecRule XML "@validateDTD /opt/apache-frontend/conf/xml.dtd" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: ReqbodyProcessor() : Variable("REQBODY_PROCESSOR") { } diff --git a/src/variables/reqbody_processor_error.h b/src/variables/reqbody_processor_error.h index bf256a01d..7d251dbfd 100644 --- a/src/variables/reqbody_processor_error.h +++ b/src/variables/reqbody_processor_error.h @@ -30,6 +30,23 @@ class Transaction; namespace Variables { class ReqbodyProcessorError : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: REQBODY_PROCESSOR_ERROR + + \verbatim + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: ReqbodyProcessorError() : Variable("REQBODY_PROCESSOR_ERROR") { } diff --git a/src/variables/reqbody_processor_error_msg.h b/src/variables/reqbody_processor_error_msg.h index 2c07e5d55..fe5239320 100644 --- a/src/variables/reqbody_processor_error_msg.h +++ b/src/variables/reqbody_processor_error_msg.h @@ -30,6 +30,23 @@ class Transaction; namespace Variables { class ReqbodyProcessorErrorMsg : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: PROCESSOR_ERROR_MSG + + \verbatim + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: ReqbodyProcessorErrorMsg() : Variable("PROCESSOR_ERROR_MSG") { } diff --git a/src/variables/request_base_name.h b/src/variables/request_base_name.h index 05d31a7f9..971dd94fc 100644 --- a/src/variables/request_base_name.h +++ b/src/variables/request_base_name.h @@ -30,6 +30,33 @@ class Transaction; namespace Variables { class RequestBasename : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: REQUEST_BASENAME + + \verbatim + This variable holds just the filename part of REQUEST_FILENAME (e.g., + index.php). + + = SecRule REQUEST_BASENAME "^login\.php$" phase:2,id:42,t:none,t:lowercase + + Note: Please note that anti-evasion transformations are not applied to this + variable by default. REQUEST_BASENAME will recognise both / and \ as path + separators. You should understand that the value of this variable depends + on what was provided in request, and that it does not have to correspond to + the resource (on disk) that will be used by the web server. + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: RequestBasename() : Variable("REQUEST_BASENAME") { } diff --git a/src/variables/request_body.h b/src/variables/request_body.h index f4a875269..792b8ec8e 100644 --- a/src/variables/request_body.h +++ b/src/variables/request_body.h @@ -30,6 +30,29 @@ class Transaction; namespace Variables { class RequestBody : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: REQUEST_BODY + + \verbatim + Holds the raw request body. This variable is available only if the + URLENCODED request body processor was used, which will occur by default + when the application/x-www-form-urlencoded content type is detected, or if + the use of the URLENCODED request body parser was forced. + + = SecRule REQUEST_BODY "^username=\w{25,}\&password=\w{25,}\&Submit\=login$" "id:43" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: RequestBody() : Variable("REQUEST_BODY") { } diff --git a/src/variables/request_body_length.h b/src/variables/request_body_length.h index ffb88d56e..e7127a8e2 100644 --- a/src/variables/request_body_length.h +++ b/src/variables/request_body_length.h @@ -30,6 +30,24 @@ class Transaction; namespace Variables { class RequestBodyLength : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: REQUEST_BODY_LENGTH + + \verbatim + Contains the number of bytes read from a request body. + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: RequestBodyLength() : Variable("REQUEST_BODY_LENGTH") { } diff --git a/src/variables/request_cookies.h b/src/variables/request_cookies.h index 772e8259f..5c3869e88 100644 --- a/src/variables/request_cookies.h +++ b/src/variables/request_cookies.h @@ -30,6 +30,29 @@ class Transaction; namespace Variables { class RequestCookies_DictElement : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: REQUEST_COOKIES + + \verbatim + This variable is a collection of all of request cookies (values 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" "id:44" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: explicit RequestCookies_DictElement(std::string dictElement) : Variable("REQUEST_COOKIES" + std::string(":") + diff --git a/src/variables/request_cookies_names.h b/src/variables/request_cookies_names.h index 4574ad59d..594f53e84 100644 --- a/src/variables/request_cookies_names.h +++ b/src/variables/request_cookies_names.h @@ -30,6 +30,28 @@ class Transaction; namespace Variables { class RequestCookiesNames_DictElement : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: REQUEST_COOKIES_NAMES + + \verbatim + 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" "id:45" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: explicit RequestCookiesNames_DictElement(std::string dictElement) : Variable("REQUEST_COOKIES_NAMES" + std::string(":") + diff --git a/src/variables/request_file_name.h b/src/variables/request_file_name.h index c1f993412..c538d1ca2 100644 --- a/src/variables/request_file_name.h +++ b/src/variables/request_file_name.h @@ -30,6 +30,31 @@ class Transaction; namespace Variables { class RequestFilename : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: REQUEST_FILENAME + + \verbatim + 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,id:46,t:none,t:normalizePath + + Note: Please note that anti-evasion transformations are not used on + REQUEST_FILENAME, which means that you will have to specify them in the + rules that use this variable. + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: RequestFilename() : Variable("REQUEST_FILENAME") { } diff --git a/src/variables/request_headers.h b/src/variables/request_headers.h index 93fd5cd4e..fdf1311e4 100644 --- a/src/variables/request_headers.h +++ b/src/variables/request_headers.h @@ -30,6 +30,33 @@ class Transaction; namespace Variables { class RequestHeaders_DictElement : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: REQUEST_HEADERS + + \verbatim + This variable can be used as either a collection of all of the request + headers or can be used to inspect selected headers (by using the + REQUEST_HEADERS:Header-Name syntax). + + = SecRule REQUEST_HEADERS:Host "^[\d\.]+$" "deny,id:47,log,status:400,msg:'Host header is a numeric IP address'" + + Note: ModSecurity will treat multiple headers that have identical names in + accordance with how the webserver treats them. For Apache this means that + they will all be concatenated into a single header with a comma as the + deliminator. + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: explicit RequestHeaders_DictElement(std::string dictElement) : Variable("REQUEST_HEADERS" + std::string(":") + diff --git a/src/variables/request_headers_names.h b/src/variables/request_headers_names.h index 6c211edec..b6489421f 100644 --- a/src/variables/request_headers_names.h +++ b/src/variables/request_headers_names.h @@ -30,6 +30,26 @@ class Transaction; namespace Variables { class RequestHeadersNames_DictElement : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: REQUEST_HEADERS_NAMES + + \verbatim + This variable is a collection of the names of all of the request headers. + + = SecRule REQUEST_HEADERS_NAMES "^x-forwarded-for" "log,deny,id:48,status:403,t:lowercase,msg:'Proxy Server Used'" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: explicit RequestHeadersNames_DictElement(std::string dictElement) : Variable("REQUEST_HEADERS_NAMES" + std::string(":") + diff --git a/src/variables/request_line.h b/src/variables/request_line.h index a3015f076..885a1a1cd 100644 --- a/src/variables/request_line.h +++ b/src/variables/request_line.h @@ -30,6 +30,29 @@ class Transaction; namespace Variables { class RequestLine : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: REQUEST_LINE + + \verbatim + This variable holds the complete request line sent to the server (including + the request method and HTTP version information). + + = # 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,id:49,log,block,t:none" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: RequestLine() : Variable("REQUEST_LINE") { } diff --git a/src/variables/request_method.h b/src/variables/request_method.h index 01062036a..2f8de1e74 100644 --- a/src/variables/request_method.h +++ b/src/variables/request_method.h @@ -30,6 +30,26 @@ class Transaction; namespace Variables { class RequestMethod : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: REQUEST_METHOD + + \verbatim + This variable holds the request method used in the transaction. + + = SecRule REQUEST_METHOD "^(?:CONNECT|TRACE)$" "id:50,t:none" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: RequestMethod() : Variable("REQUEST_METHOD") { } diff --git a/src/variables/request_protocol.h b/src/variables/request_protocol.h index 9a9c0da13..7e79595b4 100644 --- a/src/variables/request_protocol.h +++ b/src/variables/request_protocol.h @@ -30,6 +30,26 @@ class Transaction; namespace Variables { class RequestProtocol : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: REQUEST_PROTOCOL + + \verbatim + This variable holds the request protocol version information. + + = SecRule REQUEST_PROTOCOL "!^HTTP/(0\.9|1\.0|1\.1)$" "id:51" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: RequestProtocol() : Variable("REQUEST_PROTOCOL") { } diff --git a/src/variables/request_uri.h b/src/variables/request_uri.h index 34d041a0b..5ad11df7a 100644 --- a/src/variables/request_uri.h +++ b/src/variables/request_uri.h @@ -30,6 +30,32 @@ class Transaction; namespace Variables { class RequestURI : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: REQUEST_URI + + \verbatim + This variable holds the full request URL including the query string data + (e.g., /index.php? p=X). However, it will never contain a domain name, even + if it was provided on the request line. + + = SecRule REQUEST_URI "attack" "phase:1,id:52,t:none,t:urlDecode,t:lowercase,t:normalizePath" + + Note: Please note that anti-evasion transformations are not used on + REQUEST_URI, which means that you will have to specify them in the rules + that use this variable. + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: RequestURI() : Variable("REQUEST_URI") { } diff --git a/src/variables/request_uri_raw.h b/src/variables/request_uri_raw.h index adb2922d3..128990303 100644 --- a/src/variables/request_uri_raw.h +++ b/src/variables/request_uri_raw.h @@ -30,6 +30,31 @@ class Transaction; namespace Variables { class RequestURIRaw : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: REQUEST_URI_RAW + + \verbatim + Same as REQUEST_URI but will contain the domain name if it was provided on + the request line (e.g., http://www.example.com/index.php?p=X). + + = SecRule REQUEST_URI_RAW "http:/" "phase:1,id:53,t:none,t:urlDecode,t:lowercase,t:normalizePath" + + Note: Please note that anti-evasion transformations are not used on + REQUEST_URI_RAW, which means that you will have to specify them in the + rules that use this variable. + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: RequestURIRaw() : Variable("REQUEST_URI_RAW") { } diff --git a/src/variables/resource.h b/src/variables/resource.h index f0bacb10d..b5ac08e4b 100644 --- a/src/variables/resource.h +++ b/src/variables/resource.h @@ -32,6 +32,23 @@ namespace Variables { class Resource_DictElement : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: RESOURCE + + \verbatim + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: explicit Resource_DictElement(std::string dictElement) : Variable("RESOURCE:" + dictElement), diff --git a/src/variables/response_body.h b/src/variables/response_body.h index 9efff09ce..9d3b881e9 100644 --- a/src/variables/response_body.h +++ b/src/variables/response_body.h @@ -30,6 +30,27 @@ class Transaction; namespace Variables { class ResponseBody : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: RESPONSE_BODY + + \verbatim + 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,id:54,t:none" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: ResponseBody() : Variable("RESPONSE_BODY") { } diff --git a/src/variables/response_content_length.h b/src/variables/response_content_length.h index 2ee9ee776..63ef48a29 100644 --- a/src/variables/response_content_length.h +++ b/src/variables/response_content_length.h @@ -30,6 +30,30 @@ class Transaction; namespace Variables { class ResponseContentLength : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: RESPONSE_CONTENT_LENGTH + + \verbatim + Response body length in bytes. Can be available starting with phase 3, but + it does not have to be (as the length of response body is not always known + in advance). If the size is not known, this variable will contain a zero. + If RESPONSE_CONTENT_LENGTH contains a zero in phase 5 that means the actual + size of the response body was 0. The value of this variable can change + between phases if the body is modified. For example, in embedded mode, + mod_deflate can compress the response body between phases 4 and 5. + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: ResponseContentLength() : Variable("RESPONSE_CONTENT_LENGTH") { } diff --git a/src/variables/response_content_type.h b/src/variables/response_content_type.h index 904e697ea..3c3bbc989 100644 --- a/src/variables/response_content_type.h +++ b/src/variables/response_content_type.h @@ -30,6 +30,28 @@ class Transaction; namespace Variables { class ResponseContentType : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: RESPONSE_CONTENT_TYPE + + \verbatim + Response content type. Available only starting with phase 3. The value + available in this variable is taken directly from the internal structures + of Apache, which means that it may contain the information that is not yet + available in response headers. In embedded deployments, you should always + refer to this variable, rather than to RESPONSE_HEADERS:Content-Type. + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: ResponseContentType() : Variable("RESPONSE_CONTENT_TYPE") { } diff --git a/src/variables/response_headers.h b/src/variables/response_headers.h index 3b272b50c..e15f81849 100644 --- a/src/variables/response_headers.h +++ b/src/variables/response_headers.h @@ -30,6 +30,32 @@ class Transaction; namespace Variables { class ResponseHeaders_DictElement : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: RESPONSE_HEADERS + + \verbatim + This variable refers to response headers, in the same way as + REQUEST_HEADERS does to request headers. + + = 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 client. This data should be + available in phase 5 or when deployed in proxy mode. + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: explicit ResponseHeaders_DictElement(std::string dictElement) : Variable("RESPONSE_HEADERS" + std::string(":") + diff --git a/src/variables/response_headers_names.h b/src/variables/response_headers_names.h index 3f80b0b81..70864f8d6 100644 --- a/src/variables/response_headers_names.h +++ b/src/variables/response_headers_names.h @@ -30,6 +30,28 @@ class Transaction; namespace Variables { class ResponseHeadersNames_DictElement : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: RESPONSE_HEADERS_NAMES + + \verbatim + This variable is a collection of the response header names. + + = SecRule RESPONSE_HEADERS_NAMES "Set-Cookie" "phase:3,id:56,t:none" + + The same limitations apply as the ones discussed in RESPONSE_HEADERS. + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: explicit ResponseHeadersNames_DictElement(std::string dictElement) : Variable("RESPONSE_HEADERS_NAMES" + std::string(":") + diff --git a/src/variables/response_protocol.h b/src/variables/response_protocol.h index f3e811412..682738542 100644 --- a/src/variables/response_protocol.h +++ b/src/variables/response_protocol.h @@ -30,6 +30,26 @@ class Transaction; namespace Variables { class ResponseProtocol : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: RESPONSE_PROTOCOL + + \verbatim + This variable holds the HTTP response protocol information. + + = SecRule RESPONSE_PROTOCOL "^HTTP\/0\.9" "phase:3,id:57,t:none" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: ResponseProtocol() : Variable("RESPONSE_PROTOCOL") { } diff --git a/src/variables/response_status.h b/src/variables/response_status.h index 3f914275f..c38193d50 100644 --- a/src/variables/response_status.h +++ b/src/variables/response_status.h @@ -30,6 +30,30 @@ class Transaction; namespace Variables { class ResponseStatus : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: RESPONSE_STATUS + + \verbatim + This variable holds the HTTP response status code: + + = 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). + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: ResponseStatus() : Variable("RESPONSE_STATUS") { } diff --git a/src/variables/rule.h b/src/variables/rule.h index 378094159..007a82819 100644 --- a/src/variables/rule.h +++ b/src/variables/rule.h @@ -28,6 +28,26 @@ class Transaction; namespace Variables { class Rule_DictElement : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: RULE + + \verbatim + This is a special collection that provides access to the id, rev, 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. + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: explicit Rule_DictElement(std::string dictElement) : Variable("RULE" + std::string(":") + diff --git a/src/variables/server_addr.h b/src/variables/server_addr.h index 5bf7386c0..c70fbbd0c 100644 --- a/src/variables/server_addr.h +++ b/src/variables/server_addr.h @@ -30,6 +30,26 @@ class Transaction; namespace Variables { class ServerAddr : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: SERVER_ADDR + + \verbatim + This variable contains the IP address of the server. + + = SecRule SERVER_ADDR "@ipMatch 192.168.1.100" "id:67" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: ServerAddr() : Variable("SERVER_ADDR") { } diff --git a/src/variables/server_name.h b/src/variables/server_name.h index eaa47cb69..50c0fd349 100644 --- a/src/variables/server_name.h +++ b/src/variables/server_name.h @@ -30,6 +30,28 @@ class Transaction; namespace Variables { class ServerName : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: SERVER_NAME + + \verbatim + 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$" "id:68" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: ServerName() : Variable("SERVER_NAME") { } diff --git a/src/variables/server_port.h b/src/variables/server_port.h index f00f9042f..554024a16 100644 --- a/src/variables/server_port.h +++ b/src/variables/server_port.h @@ -30,6 +30,27 @@ class Transaction; namespace Variables { class ServerPort : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: SERVER_PORT + + \verbatim + This variable contains the local port that the web server (or reverse + proxy) is listening on. + + = SecRule SERVER_PORT "^80$" "id:69" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: ServerPort() : Variable("SERVER_PORT") { } diff --git a/src/variables/session.h b/src/variables/session.h index 0a3f8a7a3..c358a41cb 100644 --- a/src/variables/session.h +++ b/src/variables/session.h @@ -32,6 +32,43 @@ namespace Variables { class Session_DictElement : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: SESSION + + \verbatim + This variable is a collection that contains session information. It becomes + available only after setsid is executed. + + The following example shows how to initialize SESSION using setsid, how to + use setvar to increase the SESSION.score values, how to set the + SESSION.blocked variable, and finally, how to deny the connection based on + the SESSION:blocked value: + + = # Initialize session storage + = 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,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,id:72,pass,setvar:SESSION.blocked=1" + = + = # Enforce session block + = SecRule SESSION:blocked "@eq 1" "phase:2,id:73,deny,status:403" + + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: explicit Session_DictElement(std::string dictElement) : Variable("SESSION"), diff --git a/src/variables/session_id.h b/src/variables/session_id.h index 30202df06..f93e3bd71 100644 --- a/src/variables/session_id.h +++ b/src/variables/session_id.h @@ -30,6 +30,25 @@ class Transaction; namespace Variables { class SessionID : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: SESSIONID + + \verbatim + This variable contains the value set with setsid. See SESSION (above) for a + complete example. + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: SessionID() : Variable("SESSIONID") { } diff --git a/src/variables/status.h b/src/variables/status.h index a556943bb..91b04b823 100644 --- a/src/variables/status.h +++ b/src/variables/status.h @@ -30,6 +30,23 @@ class Transaction; namespace Variables { class Status : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: STATUS + + \verbatim + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: Status() : Variable("STATUS") { } diff --git a/src/variables/time.h b/src/variables/time.h index 3a7cbe0cb..c9b1a0a8b 100644 --- a/src/variables/time.h +++ b/src/variables/time.h @@ -30,6 +30,26 @@ class Transaction; namespace Variables { class Time : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: TIME + + \verbatim + 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}$" "id:74" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: explicit Time(std::string _name) : Variable(_name), diff --git a/src/variables/time_day.h b/src/variables/time_day.h index c00e27212..c8570bdf0 100644 --- a/src/variables/time_day.h +++ b/src/variables/time_day.h @@ -29,6 +29,28 @@ class Transaction; namespace Variables { class TimeDay : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: TIME_DAY + + \verbatim + 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)$" "id:75" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: explicit TimeDay(std::string _name) : Variable(_name), diff --git a/src/variables/time_epoch.h b/src/variables/time_epoch.h index e30808f40..0f4069185 100644 --- a/src/variables/time_epoch.h +++ b/src/variables/time_epoch.h @@ -29,6 +29,24 @@ class Transaction; namespace Variables { class TimeEpoch : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: TIME_EPOCH + + \verbatim + This variable holds the time in seconds since 1970. + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: explicit TimeEpoch(std::string _name) : Variable(_name), diff --git a/src/variables/time_hour.h b/src/variables/time_hour.h index 97bbdeba9..53cbbd84d 100644 --- a/src/variables/time_hour.h +++ b/src/variables/time_hour.h @@ -29,6 +29,27 @@ class Transaction; namespace Variables { class TimeHour : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: TIME_HOUR + + \verbatim + 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))$" "id:76" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: explicit TimeHour(std::string _name) : Variable(_name), diff --git a/src/variables/time_min.h b/src/variables/time_min.h index 8d1d21cc3..a0baff6ce 100644 --- a/src/variables/time_min.h +++ b/src/variables/time_min.h @@ -29,6 +29,27 @@ class Transaction; namespace Variables { class TimeMin : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: TIME_MIN + + \verbatim + 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)" "id:77" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: explicit TimeMin(std::string _name) : Variable(_name), diff --git a/src/variables/time_mon.h b/src/variables/time_mon.h index 222844523..365360c6e 100644 --- a/src/variables/time_mon.h +++ b/src/variables/time_mon.h @@ -29,6 +29,27 @@ class Transaction; namespace Variables { class TimeMon : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: TIME_MON + + \verbatim + 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" "id:78" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: explicit TimeMon(std::string _name) : Variable(_name), diff --git a/src/variables/time_sec.h b/src/variables/time_sec.h index 944987b97..b9df09b14 100644 --- a/src/variables/time_sec.h +++ b/src/variables/time_sec.h @@ -29,6 +29,26 @@ class Transaction; namespace Variables { class TimeSec : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: TIME_SEC + + \verbatim + This variable holds the current second value (0–59). + + = SecRule TIME_SEC "@gt 30" "id:79" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: explicit TimeSec(std::string _name) : Variable(_name), diff --git a/src/variables/time_wday.h b/src/variables/time_wday.h index ff84e12e6..458b54af6 100644 --- a/src/variables/time_wday.h +++ b/src/variables/time_wday.h @@ -29,6 +29,27 @@ class Transaction; namespace Variables { class TimeWDay : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: TIME_WDAY + + \verbatim + This variable holds the current weekday value (0–6). The following rule + triggers only on Saturday and Sunday: + + = SecRule TIME_WDAY "^(0|6)$" "id:80" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: explicit TimeWDay(std::string _name) : Variable(_name), diff --git a/src/variables/time_year.h b/src/variables/time_year.h index 1d5b2c3df..ee789b94c 100644 --- a/src/variables/time_year.h +++ b/src/variables/time_year.h @@ -29,6 +29,26 @@ class Transaction; namespace Variables { class TimeYear : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: TIME_YEAR + + \verbatim + This variable holds the current four-digit year value. + + = SecRule TIME_YEAR "^2006$" "id:81" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: explicit TimeYear(std::string _name) : Variable(_name), diff --git a/src/variables/tx.h b/src/variables/tx.h index 73de5eaa7..6915687d6 100644 --- a/src/variables/tx.h +++ b/src/variables/tx.h @@ -32,6 +32,40 @@ namespace Variables { class Tx_DictElement : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: TX + + \verbatim + This is the transient transaction collection, which is used to store pieces + of data, create a transaction anomaly score, and so on. The variables + placed into this collection are available only until the transaction is + complete. + + = # Increment transaction attack score on attack + = 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,id:83,log,deny" + + Some variable names in the TX collection are reserved and cannot be used: + + - TX:0: the matching value when using the @rx or @pm operator with the capture action + - TX:1-TX:9: the captured subexpression value when using the @rx operator with capturing parens and the capture action + - TX:MSC_.*: ModSecurity processing flags + - MSC_PCRE_LIMITS_EXCEEDED: Set to nonzero if PCRE match limits are exceeded. See SecPcreMatchLimit and SecPcreMatchLimitRecursion for more information. + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: explicit Tx_DictElement(std::string dictElement) : Variable("TX:" + dictElement), diff --git a/src/variables/unique_id.h b/src/variables/unique_id.h index 2530ce924..5a794eac4 100644 --- a/src/variables/unique_id.h +++ b/src/variables/unique_id.h @@ -30,6 +30,24 @@ class Transaction; namespace Variables { class UniqueID : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: UNIQUEID + + \verbatim + + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: UniqueID() : Variable("UNIQUEID") { } diff --git a/src/variables/url_encoded_error.h b/src/variables/url_encoded_error.h index a12b92f7a..790efb184 100644 --- a/src/variables/url_encoded_error.h +++ b/src/variables/url_encoded_error.h @@ -30,6 +30,29 @@ class Transaction; namespace Variables { class UrlEncodedError : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: URLENCODED_ERROR + + \verbatim + This variable is created when an invalid URL encoding is encountered during + the parsing of a query string (on every request) or during the parsing of + an application/x-www-form-urlencoded request body (only on the requests + that use the URLENCODED request body processor). + + + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: UrlEncodedError() : Variable("URLENCODED_ERROR") { } diff --git a/src/variables/user.h b/src/variables/user.h index abd4e5c63..c682b29e7 100644 --- a/src/variables/user.h +++ b/src/variables/user.h @@ -32,6 +32,23 @@ namespace Variables { class User_DictElement : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: USER + + \verbatim + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: explicit User_DictElement(std::string dictElement) : Variable("USER"), diff --git a/src/variables/user_id.h b/src/variables/user_id.h index 9393637e8..702b37659 100644 --- a/src/variables/user_id.h +++ b/src/variables/user_id.h @@ -30,6 +30,30 @@ class Transaction; namespace Variables { class UserID : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: USERID + + \verbatim + This variable contains the value set with setuid. + + = # Initialize user tracking + = SecAction "nolog,id:84,pass,setuid:%{REMOTE_USER}" + = + = # Is the current user the administrator? + = SecRule USERID "admin" "id:85" + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: UserID() : Variable("USERID") { } diff --git a/src/variables/web_app_id.h b/src/variables/web_app_id.h index 41e91c95c..e3f570a54 100644 --- a/src/variables/web_app_id.h +++ b/src/variables/web_app_id.h @@ -31,6 +31,26 @@ class Transaction; namespace Variables { class WebAppId : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: WEBAPPID + + \verbatim + This variable contains the current application name, which is set in + configuration using SecWebAppId. + + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: WebAppId() : Variable("WEBAPPID") { } diff --git a/src/variables/xml.h b/src/variables/xml.h index d852bdd23..17e1e1c93 100644 --- a/src/variables/xml.h +++ b/src/variables/xml.h @@ -35,6 +35,80 @@ namespace Variables { * with functions that manipulate the document tree. */ class XML_NoDictElement : public Variable { + /** @ingroup ModSecurity_Variables ModSecurity_RefManual ModSecurity_RefManualVar */ + /** + + Description + + Name: XML + + \verbatim + Special collection used to interact with the XML parser. It can be 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,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 "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 against + payload such as this one: + + = + = + = Fred Jones + =
+ = 900 Aurora Ave. + = Seattle + = WA + = 98115 + =
+ =
+ = 2011 152nd Avenue NE + = Redmond + = WA + = 98052 + =
+ = (425)555-5665 + = (206)555-5555 + = (206)555-4321 + =
+ =
+ = The second XPath expression does use namespaces. It would match the following payload: + + = + = + = Fred Jones + =
+ = 900 Aurora Ave. + = Seattle + = WA + = 98115 + =
+ =
+ = 2011 152nd Avenue NE + = Redmond + = WA + = 98052 + =
+ = (425)555-5665 + = (206)555-5555 + = (206)555-4321 + =
+ =
+ Note the different namespace used in the second example. + \endverbatim + + + Details + + \verbatim + \endverbatim + + */ public: XML_NoDictElement() : Variable("XML"),