14

In ModSecurity there are PCRE limits exceeded errors.

I know I can fix this by setting rules such as:

SecPcreMatchLimit 150000
SecPcreMatchLimitRecursion 150000

But, what are these rules actually doing? What does the PCRE limit recursion set to 150,000 mean? What security holes am I allowing through by setting these so high? What does the recursion and limit mean?

I know there is documentation, but the documentation doesn't actually tell me what is going on, it simply tells me how to work with the directives.

1
  • I'm editing this post to change the "perl" tag to "pcre". PCRE is not Perl, despite what the acronym would have you believe. Nov 2, 2012 at 17:30

2 Answers 2

14

These appear to be settings internal to the PCRE engine in order to limit the maximum amount of memory/time spent on trying to match some text to a pattern. The pcreapi manpage does little to explain it in layman's terms:

The match_limit field provides a means of preventing PCRE from using up a vast amount of resources when running patterns that are not going to match, but which have a very large number of possibilities in their search trees. The classic example is the use of nested unlimited repeats.

Internally, PCRE uses a function called match() which it calls repeatedly (sometimes recursively). The limit set by match_limit is imposed on the number of times this function is called during a match, which has the effect of limiting the amount of backtracking that can take place. For patterns that are not anchored, the count restarts from zero for each position in the subject string.

The default value for the limit can be set when PCRE is built; the default default is 10 million, which handles all but the most extreme cases. You can override the default by suppling pcre_exec() with a pcre_extra block in which match_limit is set, and PCRE_EXTRA_MATCH_LIMIT is set in the flags field. If the limit is exceeded, pcre_exec() returns PCRE_ERROR_MATCHLIMIT.

The match_limit_recursion field is similar to match_limit, but instead of limiting the total number of times that match() is called, it limits the depth of recursion. The recursion depth is a smaller number than the total number of calls, because not all calls to match() are recursive. This limit is of use only if it is set smaller than match_limit.

Since the PCRE library built-in default is 10000000, my guess is that the lower setting is suggested for mod_security in order to prevent requests from being held up for a long time.

2
  • modsecurity seems to have a default value of 1500, which is significantly lower than 1M. OP's value of 150000 would then be increasing the setting, not decreasing it. Oct 11, 2016 at 13:42
  • The small limit of 1500 makes sense in the wake of ReDoS attacks. CloudFlare's Lua WAF used PCRE without changes to the limits and they got really messed up in 2019. Feb 4 at 4:09
0

The values you see inside mod_security.conf are part of a RegEx DoS rule:

SecPcreMatchLimit 10000
SecPcreMatchLimitRecursion 10000
SecRule TX:/^MSC_/ "!@Streq 0"
"id:'200004',phase:2,t:none,deny,msg:'ModSecurity internal error flagged:
%{MATCHED_VAR_NAME}'"

You must log in to answer this question.