Added PCRE limits and studying by default to help alleviate REDoS reported by Sogeti/ESEC R&D (MODSEC-119).

This commit is contained in:
b1v1r
2010-02-05 18:09:19 +00:00
parent d66760d09c
commit 589274903d
13 changed files with 544 additions and 114 deletions

View File

@@ -84,7 +84,7 @@ static int msre_op_rx_param_init(msre_rule *rule, char **error_msg) {
*error_msg = NULL;
/* Compile pattern */
regex = msc_pregcomp(rule->ruleset->mp, pattern, PCRE_DOTALL | PCRE_DOLLAR_ENDONLY, &errptr, &erroffset);
regex = msc_pregcomp_ex(rule->ruleset->mp, pattern, PCRE_DOTALL | PCRE_DOLLAR_ENDONLY, &errptr, &erroffset, msc_pcre_match_limit, msc_pcre_match_limit_recursion);
if (regex == NULL) {
*error_msg = apr_psprintf(rule->ruleset->mp, "Error compiling pattern (offset %d): %s",
erroffset, errptr);
@@ -141,8 +141,29 @@ static int msre_op_rx_execute(modsec_rec *msr, msre_rule *rule, msre_var *var, c
* and no memory has to be allocated for any backreferences.
*/
rc = msc_regexec_capture(regex, target, target_length, ovector, 30, &my_error_msg);
if (rc < -1) {
*error_msg = apr_psprintf(msr->mp, "Regex execution failed: %s", my_error_msg);
if ((rc == PCRE_ERROR_MATCHLIMIT) || (rc == PCRE_ERROR_RECURSIONLIMIT)) {
msc_string *s = (msc_string *)apr_pcalloc(msr->mp, sizeof(msc_string));
if (s == NULL) return -1;
s->name = apr_pstrdup(msr->mp, "MSC_PCRE_LIMITS_EXCEEDED");
s->name_len = strlen(s->name);
s->value = apr_pstrdup(msr->mp, "1");
s->value_len = 1;
if ((s->name == NULL)||(s->value == NULL)) return -1;
apr_table_setn(msr->tx_vars, s->name, (void *)s);
*error_msg = apr_psprintf(msr->mp,
"Rule execution error - "
"PCRE limits exceeded (%d): %s",
rc, my_error_msg);
msr_log(msr, 3, "%s.", *error_msg);
return 0; /* No match. */
}
else if (rc < -1) {
*error_msg = apr_psprintf(msr->mp, "Regex execution failed (%d): %s",
rc, my_error_msg);
return -1;
}
@@ -1053,7 +1074,7 @@ static int msre_op_verifyCC_init(msre_rule *rule, char **error_msg) {
*error_msg = NULL;
/* Compile rule->op_param */
regex = msc_pregcomp(rule->ruleset->mp, rule->op_param, PCRE_DOTALL | PCRE_MULTILINE, &errptr, &erroffset);
regex = msc_pregcomp_ex(rule->ruleset->mp, rule->op_param, PCRE_DOTALL | PCRE_MULTILINE, &errptr, &erroffset, msc_pcre_match_limit, msc_pcre_match_limit_recursion);
if (regex == NULL) {
*error_msg = apr_psprintf(rule->ruleset->mp, "Error compiling pattern (offset %d): %s",
erroffset, errptr);