diff --git a/content/3-reference-manual/3-10-recommended-base-configuration.md b/content/3-reference-manual/3-10-recommended-base-configuration.md index 796d947..d3867df 100644 --- a/content/3-reference-manual/3-10-recommended-base-configuration.md +++ b/content/3-reference-manual/3-10-recommended-base-configuration.md @@ -156,8 +156,10 @@ SecRule TX:/^MSC_/ "!@streq 0" \ The PCRE limits cap the work a single regular expression may do, against regular-expression denial of service. When a limit is hit the engine sets `TX:MSC_PCRE_LIMITS_EXCEEDED` instead of matching, and rule 200005 turns any such -`MSC_` flag into a denial. In v3 `SecPcreMatchLimitRecursion` is accepted but ignored, and the match limit is -honored since 3.0.10. +`MSC_` flag into a denial. Since 2.9.16, v2 also sets `TX:MSC_PCRE_ERROR` when a pattern is invalid after macro +expansion, and this rule catches it too. In v3 `SecPcreMatchLimitRecursion` is accepted but ignored, and the match limit +is honored since 3.0.10. v3 sets `TX:MSC_PCRE_ERROR` on any regex error since 3.0.18. Earlier v3 releases report +these errors only in the standalone `MSC_PCRE_ERROR` variable, which `TX:/^MSC_/` does not see. ## Response body handling diff --git a/content/3-reference-manual/3-3-variables.md b/content/3-reference-manual/3-3-variables.md index 5b32be6..4452024 100644 --- a/content/3-reference-manual/3-3-variables.md +++ b/content/3-reference-manual/3-3-variables.md @@ -412,7 +412,9 @@ SecRule ARGS "@pm some key words" "id:12345,deny,status:500" {{< secmeta v2="no" v3="3.0.10" >}} -libModSecurity v3 only: set to 1 when the @rx or @rxGlobal operator fails with any PCRE error, for example an invalid pattern after macro expansion or a match-limit error (in the latter case MSC_PCRE_LIMITS_EXCEEDED is set as well). ModSecurity v2 has no equivalent variable. +MSC_PCRE_ERROR will be set to 1 when the @rx or @rxGlobal operator fails with any PCRE error, for example an invalid pattern after macro expansion or a match-limit error (in the latter case MSC_PCRE_LIMITS_EXCEEDED is set as well). + +ModSecurity v2 does not provide this as a standalone variable. Since 2.9.16, when the @rx pattern is invalid after macro expansion, or a regex execution fails with an error other than a PCRE limit, v2 sets the transaction variable TX:MSC_PCRE_ERROR to 1. Rule 200005 in modsecurity.conf-recommended (`SecRule TX:/^MSC_/ "!@streq 0"`) catches it. Since 3.0.18, libModSecurity v3 also sets TX:MSC_PCRE_ERROR next to the standalone variable, for every @rx or @rxGlobal error including an exceeded match limit. Earlier v3 releases set only the standalone variable, which rule 200005 does not see. ## MSC_PCRE_LIMITS_EXCEEDED @@ -1391,6 +1393,7 @@ Some variable names in the TX collection are reserved and cannot be used: - TX:1-TX:9: the captured subexpression value when using the @rx operator with capturing parens and the capture action. ModSecurity v2 stores at most nine captures (TX:1 to TX:9); libModSecurity v3 stores every capturing group of the expression (the v3 manual documents TX:1 to TX:99). - 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. +- MSC_PCRE_ERROR: Set to 1 when a regular expression fails, for example an invalid pattern after macro expansion. Set since ModSecurity 2.9.16, which leaves it unset for PCRE limit errors, and since libModSecurity 3.0.18. See MSC_PCRE_ERROR. ## UNIQUE_ID diff --git a/content/3-reference-manual/3-6-operators.md b/content/3-reference-manual/3-6-operators.md index 61bb746..7572bb2 100644 --- a/content/3-reference-manual/3-6-operators.md +++ b/content/3-reference-manual/3-6-operators.md @@ -661,9 +661,11 @@ Regular expressions are a very powerful tool. You are strongly advised to read t Macro expansion is supported since ModSecurity 2.6.2: a pattern containing `%{...}` is expanded and compiled on every evaluation instead of once at startup. +If the expanded pattern is not a valid regular expression, or a PCRE limit is exceeded, neither @rx nor !@rx matches. The error is visible through the TX:MSC_PCRE_ERROR or TX:MSC_PCRE_LIMITS_EXCEEDED flag. Before 2.9.16, v2 did not set TX:MSC_PCRE_ERROR, and a negated !@rx matched on these errors. + {{% notice note %}} -libModSecurity v3 compiles patterns with PCRE2_DOTALL and PCRE2_MULTILINE instead, so `^` and `$` also match at inner line boundaries. Rules that need line anchors should write `(?m)` explicitly to behave the same in both versions. In v3 a pattern that is invalid at load time rejects the rule, a pattern that becomes invalid after macro expansion does not match and sets MSC_PCRE_ERROR, and an empty pattern matches everything. SecPcreMatchLimit is honored since 3.0.10: when the limit is exceeded the operator does not match and MSC_PCRE_LIMITS_EXCEEDED and TX:MSC_PCRE_LIMITS_EXCEEDED are set to 1. +libModSecurity v3 compiles patterns with PCRE2_DOTALL and PCRE2_MULTILINE instead, so `^` and `$` also match at inner line boundaries. Rules that need line anchors should write `(?m)` explicitly to behave the same in both versions. In v3 a pattern that is invalid at load time rejects the rule, a pattern that becomes invalid after macro expansion does not match and sets MSC_PCRE_ERROR (and, since 3.0.18, TX:MSC_PCRE_ERROR), and an empty pattern matches everything. SecPcreMatchLimit is honored since 3.0.10: when the limit is exceeded the operator does not match and MSC_PCRE_LIMITS_EXCEEDED and TX:MSC_PCRE_LIMITS_EXCEEDED are set to 1. {{% /notice %}}