diff --git a/Makefile.am b/Makefile.am index 734b6f3597..92e6171175 100644 --- a/Makefile.am +++ b/Makefile.am @@ -158,6 +158,7 @@ TESTS+=test/test-cases/regression/issue-2099.json TESTS+=test/test-cases/regression/issue-2000.json TESTS+=test/test-cases/regression/issue-2111.json TESTS+=test/test-cases/regression/issue-2196.json +TESTS+=test/test-cases/regression/issue-2296.json TESTS+=test/test-cases/regression/issue-394.json TESTS+=test/test-cases/regression/issue-849.json TESTS+=test/test-cases/regression/issue-960.json diff --git a/src/collection/backend/in_memory-per_process.cc b/src/collection/backend/in_memory-per_process.cc index 717f998216..630b3fd213 100644 --- a/src/collection/backend/in_memory-per_process.cc +++ b/src/collection/backend/in_memory-per_process.cc @@ -134,7 +134,7 @@ void InMemoryPerProcess::resolveRegularExpression(const std::string& var, //std::string name = std::string(var, var.find(":") + 2, // var.size() - var.find(":") - 3); //size_t keySize = col.size(); - Utils::Regex r(var); + Utils::Regex r(var, true); for (const auto& x : *this) { //if (x.first.size() <= keySize + 1) { diff --git a/src/collection/backend/lmdb.cc b/src/collection/backend/lmdb.cc index 55afb1c548..9ee05a0ed8 100644 --- a/src/collection/backend/lmdb.cc +++ b/src/collection/backend/lmdb.cc @@ -537,7 +537,7 @@ void LMDB::resolveRegularExpression(const std::string& var, MDB_stat mst; MDB_cursor *cursor; - Utils::Regex r(var); + Utils::Regex r(var, true); rc = mdb_txn_begin(m_env, NULL, 0, &txn); lmdb_debug(rc, "txn", "resolveRegularExpression"); diff --git a/src/utils/regex.cc b/src/utils/regex.cc index be56e378a0..9f5304f1e8 100644 --- a/src/utils/regex.cc +++ b/src/utils/regex.cc @@ -38,12 +38,16 @@ namespace modsecurity { namespace Utils { -Regex::Regex(const std::string& pattern_) +Regex::Regex(const std::string& pattern_, bool ignoreCase) : pattern(pattern_.empty() ? ".*" : pattern_) { const char *errptr = NULL; int erroffset; + int flags = (PCRE_DOTALL|PCRE_MULTILINE); - m_pc = pcre_compile(pattern.c_str(), PCRE_DOTALL|PCRE_MULTILINE, + if (ignoreCase == true) { + flags |= PCRE_CASELESS; + } + m_pc = pcre_compile(pattern.c_str(), flags, &errptr, &erroffset, NULL); m_pce = pcre_study(m_pc, pcre_study_opt, &errptr); diff --git a/src/utils/regex.h b/src/utils/regex.h index 7dcc4dbf61..dd47bd7a27 100644 --- a/src/utils/regex.h +++ b/src/utils/regex.h @@ -50,7 +50,7 @@ class SMatch { class Regex { public: - explicit Regex(const std::string& pattern_); + explicit Regex(const std::string& pattern_, bool ignoreCase = false); ~Regex(); // m_pc and m_pce can't be easily copied diff --git a/test/test-cases/regression/issue-2296.json b/test/test-cases/regression/issue-2296.json new file mode 100644 index 0000000000..6b73a024b6 --- /dev/null +++ b/test/test-cases/regression/issue-2296.json @@ -0,0 +1,90 @@ +[ + { + "enabled":1, + "version_min":300000, + "title":"Check TX variable case sensitivity (1/2)", + "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/2296", + "gihub_issue": 2296, + "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", + "name1": "value1" + }, + "uri":"/", + "method":"GET" + }, + "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":{ + "http_code":437, + "error_log":"`Within' with parameter `/name1/ /name2/' against variable `TX:header_name_name1'" + }, + "rules":[ + "SecRuleEngine On", + "SecAction \"id:1,phase:1,setvar:'TX.restricted_headers=/name1/ /name2/'\"", + "SecRule REQUEST_HEADERS_NAMES \"^.*$\" \"id:2,phase:2,t:none,t:lowercase,setvar:'tx.header_name_%{tx.0}=/%{tx.0}/',deny,status:437,msg:'capture',capture,chain\"", + "SecRule TX:/^header_name_/ \"@within %{tx.restricted_headers}\" \"setvar:'tx.matched=1',log\"" + ] + }, + { + "enabled":1, + "version_min":300000, + "title":"Check TX variable case sensitivity (2/2)", + "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/2296", + "gihub_issue": 2296, + "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", + "name1": "value1" + }, + "uri":"/", + "method":"GET" + }, + "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":{ + "http_code":437, + "error_log":"`Within' with parameter `/name1/ /name2/' against variable `TX:header_name_name1'" + }, + "rules":[ + "SecRuleEngine On", + "SecAction \"id:1,phase:1,setvar:'TX.restricted_headers=/name1/ /name2/'\"", + "SecRule REQUEST_HEADERS_NAMES \"^.*$\" \"id:2,phase:2,t:none,t:lowercase,setvar:'tx.header_name_%{tx.0}=/%{tx.0}/',deny,status:437,msg:'capture',capture,chain\"", + "SecRule TX:/^HEADER_NAME_/ \"@within %{tx.restricted_headers}\" \"setvar:'tx.matched=1',log\"" + ] + } +]