diff --git a/CHANGES b/CHANGES index c65f5464..9ea8e2af 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,8 @@ v3.x.y - YYYY-MMM-DD (to be released) ------------------------------------- + - Add DebugLog message for bad pattern in rx operator + [Issue #2722 - @martinhsv] - Support PCRE2 [Issue #2668 - @martinhsv] - Support SecRequestBodyNoFilesLimit diff --git a/src/operators/rx.cc b/src/operators/rx.cc index f69ca97d..13ae7550 100644 --- a/src/operators/rx.cc +++ b/src/operators/rx.cc @@ -52,6 +52,10 @@ bool Rx::evaluate(Transaction *transaction, RuleWithActions *rule, } std::vector captures; + if (re->hasError()) { + ms_dbg_a(transaction, 3, "Error with regular expression: \"" + re->pattern + "\""); + return false; + } re->searchOneMatch(input, captures); if (rule && rule->hasCaptureAction() && transaction) { diff --git a/src/utils/regex.cc b/src/utils/regex.cc index b2536aef..9b80fbf3 100644 --- a/src/utils/regex.cc +++ b/src/utils/regex.cc @@ -75,6 +75,9 @@ Regex::Regex(const std::string& pattern_, bool ignoreCase) pcre2_options, &errornumber, &erroroffset, NULL); if (m_pc != NULL) { m_match_data = pcre2_match_data_create_from_pattern(m_pc, NULL); + if (m_match_data == NULL) { + m_pc = NULL; + } } #else const char *errptr = NULL; diff --git a/src/utils/regex.h b/src/utils/regex.h index a55c6063..19a1eee5 100644 --- a/src/utils/regex.h +++ b/src/utils/regex.h @@ -72,6 +72,9 @@ class Regex { Regex(const Regex&) = delete; Regex& operator=(const Regex&) = delete; + bool hasError() const { + return (m_pc == NULL); + } std::list searchAll(const std::string& s) const; bool searchOneMatch(const std::string& s, std::vector& captures) const; bool searchGlobal(const std::string& s, std::vector& captures) const; diff --git a/test/test-cases/regression/operator-rx.json b/test/test-cases/regression/operator-rx.json index d6b9839f..f0a4957a 100644 --- a/test/test-cases/regression/operator-rx.json +++ b/test/test-cases/regression/operator-rx.json @@ -85,5 +85,47 @@ "SecRuleEngine On", "SecRule REQUEST_HEADERS:Content-Length \"!^0$\" \"id:1,phase:2,pass,t:trim,block\"" ] + }, + { + "enabled":1, + "version_min":300000, + "title":"Testing Operator :: @rx with non-compiling pattern", + "client":{ + "ip":"200.249.12.31", + "port":123 + }, + "server":{ + "ip":"200.249.12.31", + "port":80 + }, + "request":{ + "headers":{ + "Host":"localhost", + "User-Agent":"curl/7.38.0", + "Accept":"*/*", + "Content-Length": "27", + "Content-Type": "application/x-www-form-urlencoded" + }, + "uri":"/", + "method":"HEAD", + "body": [ ] + }, + "response":{ + "headers":{ + "Date":"Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type":"text/html" + }, + "body":[ + "no need." + ] + }, + "expected":{ + "debug_log":"Error with regular expression" + }, + "rules":[ + "SecRuleEngine On", + "SecRule REQUEST_HEADERS:Content-Type \"@rx a(b\" \"id:1,phase:2,pass,t:trim,block\"" + ] } ]