diff --git a/src/operators/rx.cc b/src/operators/rx.cc index de1428e2e..647dcb963 100644 --- a/src/operators/rx.cc +++ b/src/operators/rx.cc @@ -38,7 +38,8 @@ bool Rx::init(const std::string &arg, std::string *error) { bool Rx::evaluate(Transaction *transaction, RuleWithActions *rule, const std::string& input, RuleMessage &ruleMessage) { - Regex *re; + const Regex *re; + std::unique_ptr reOwned; if (m_param.empty() && !m_string->m_containsMacro) { return true; @@ -46,7 +47,8 @@ bool Rx::evaluate(Transaction *transaction, RuleWithActions *rule, if (m_string->m_containsMacro) { std::string eparam(m_string->evaluate(transaction)); - re = new Regex(eparam); + reOwned.reset(new Regex(eparam)); + re = reOwned.get(); } else { re = m_re; } @@ -100,10 +102,6 @@ bool Rx::evaluate(Transaction *transaction, RuleWithActions *rule, logOffset(ruleMessage, capture.m_offset, capture.m_length); } - if (m_string->m_containsMacro) { - delete re; - } - if (!captures.empty()) { return true; } diff --git a/src/operators/rx_global.cc b/src/operators/rx_global.cc index a966ed35b..6064e01bb 100644 --- a/src/operators/rx_global.cc +++ b/src/operators/rx_global.cc @@ -38,7 +38,8 @@ bool RxGlobal::init(const std::string &arg, std::string *error) { bool RxGlobal::evaluate(Transaction *transaction, RuleWithActions *rule, const std::string& input, RuleMessage &ruleMessage) { - Regex *re; + const Regex *re; + std::unique_ptr reOwned; if (m_param.empty() && !m_string->m_containsMacro) { return true; @@ -46,7 +47,8 @@ bool RxGlobal::evaluate(Transaction *transaction, RuleWithActions *rule, if (m_string->m_containsMacro) { std::string eparam(m_string->evaluate(transaction)); - re = new Regex(eparam); + reOwned.reset(new Regex(eparam)); + re = reOwned.get(); } else { re = m_re; } @@ -95,10 +97,6 @@ bool RxGlobal::evaluate(Transaction *transaction, RuleWithActions *rule, logOffset(ruleMessage, capture.m_offset, capture.m_length); } - if (m_string->m_containsMacro) { - delete re; - } - if (captures.size() > 0) { return true; } diff --git a/test/test-cases/regression/operator-rx.json b/test/test-cases/regression/operator-rx.json index 917a67d1b..6d926dff8 100644 --- a/test/test-cases/regression/operator-rx.json +++ b/test/test-cases/regression/operator-rx.json @@ -284,5 +284,102 @@ "SecRule ARGS:rxtest \"@rx (w+)+$\" \"id:1,phase:1,pass,t:trim,block\"", "SecRule TX:MSC_PCRE_LIMITS_EXCEEDED \"@streq 1\" \"id:2,phase:1,pass,t:trim,block\"" ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Operator :: @rx with a macro that expands to a 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": "0", + "Content-Type": "application/x-www-form-urlencoded" + }, + "uri": "/?rxtest=value1", + "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", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Error with regular expression", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecAction \"id:1,phase:1,pass,nolog,setvar:tx.pattern=(\"", + "SecRule ARGS:rxtest \"@rx %{tx.pattern}\" \"id:2,phase:1,pass,t:trim,block\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Operator :: @rx with a macro pattern and PCRE match limits exceeded", + "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": "0", + "Content-Type": "application/x-www-form-urlencoded" + }, + "uri": "/?rxtest=wwwwwwwwwwwwwwwwwwwwwowwwwwwwwwww", + "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", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "rx: regex error 'MATCH_LIMIT' for pattern", + "error_log": "Matched \"Operator `StrEq' with parameter `1' against variable `TX:MSC_PCRE_LIMITS_EXCEEDED'", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecPcreMatchLimit 2", + "SecAction \"id:1,phase:1,pass,nolog,setvar:tx.pattern=(w+)+$\"", + "SecRule ARGS:rxtest \"@rx %{tx.pattern}\" \"id:2,phase:1,pass,t:trim,block\"", + "SecRule TX:MSC_PCRE_LIMITS_EXCEEDED \"@streq 1\" \"id:3,phase:1,pass,t:trim,block\"" + ] } ]