From df9e4530f253892d599f8c61fb4cdf2b8cfd4e28 Mon Sep 17 00:00:00 2001 From: Ervin Hegedus Date: Wed, 22 Apr 2020 19:27:49 +0000 Subject: [PATCH 1/2] Regex search in collection data case insensitive fix --- Makefile.am | 1 + .../backend/in_memory-per_process.cc | 2 +- src/collection/backend/lmdb.cc | 2 +- src/utils/regex.cc | 8 +- src/utils/regex.h | 2 +- test/test-cases/regression/rule-920450.json | 87 +++++++++++++++++++ 6 files changed, 97 insertions(+), 5 deletions(-) create mode 100644 test/test-cases/regression/rule-920450.json diff --git a/Makefile.am b/Makefile.am index 734b6f3597..3160dcf08d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -185,6 +185,7 @@ TESTS+=test/test-cases/regression/request-body-parser-xml-validade-dtd.json TESTS+=test/test-cases/regression/rule-920120.json TESTS+=test/test-cases/regression/rule-920200.json TESTS+=test/test-cases/regression/rule-920274.json +TESTS+=test/test-cases/regression/rule-920450.json TESTS+=test/test-cases/regression/secaction.json TESTS+=test/test-cases/regression/secargumentslimit.json TESTS+=test/test-cases/regression/sec_component_signature.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/rule-920450.json b/test/test-cases/regression/rule-920450.json new file mode 100644 index 0000000000..990e098407 --- /dev/null +++ b/test/test-cases/regression/rule-920450.json @@ -0,0 +1,87 @@ +[ + { + "enabled":1, + "version_min":300000, + "title":"OWASP CRS id:920450", + "client":{ + "ip":"200.249.12.31", + "port":123 + }, + "server":{ + "ip":"200.249.12.31", + "port":80 + }, + "request":{ + "headers":{ + "TRANSLATE": "test" + }, + "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":403 + }, + "rules":[ + "SecRuleEngine On", + "SecRule &TX:restricted_headers \"@eq 0\" \"id:901165,phase:1,pass,nolog,setvar:'tx.restricted_headers=/proxy/ /lock-token/ /content-range/ /translate/ /if/'\"", + "SecRule REQUEST_HEADERS_NAMES \"@rx ^.*$\" \"id:920450,phase:2,capture,block,deny,t:lowercase,setvar:'tx.header_name_%{tx.0}=/%{tx.0}/',chain", + "SecRule TX:/^HEADER_NAME_/ \"@within %{tx.restricted_headers}\" \"\"" + ] + }, + { + "enabled":1, + "version_min":300000, + "title":"OWASP CRS id:920450", + "client":{ + "ip":"200.249.12.31", + "port":123 + }, + "server":{ + "ip":"200.249.12.31", + "port":80 + }, + "request":{ + "headers":{ + "Accept": "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Accept-Encoding": "gzip,deflate", + "Accept-Language": "en-us,en;q=0.5", + "Host": "localhost", + "Keep-Alive": "300", + "Proxy-Connection": "keep-alive", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv" + }, + "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":200 + }, + "rules":[ + "SecRuleEngine On", + "SecRule &TX:restricted_headers \"@eq 0\" \"id:901165,phase:1,pass,nolog,setvar:'tx.restricted_headers=/proxy/ /lock-token/ /content-range/ /translate/ /if/'\"", + "SecRule REQUEST_HEADERS_NAMES \"@rx ^.*$\" \"id:920450,phase:2,capture,block,deny,t:lowercase,setvar:'tx.header_name_%{tx.0}=/%{tx.0}/',chain", + "SecRule TX:/^HEADER_NAME_/ \"@within %{tx.restricted_headers}\" \"\"" + ] + } +] From ceb0e381d0338442b6d4761c9847630202611673 Mon Sep 17 00:00:00 2001 From: Ervin Hegedus Date: Fri, 23 Oct 2020 20:41:01 +0000 Subject: [PATCH 2/2] Replace regression test as it expected --- Makefile.am | 2 +- test/test-cases/regression/issue-2296.json | 90 +++++++++++++++++++++ test/test-cases/regression/rule-920450.json | 87 -------------------- 3 files changed, 91 insertions(+), 88 deletions(-) create mode 100644 test/test-cases/regression/issue-2296.json delete mode 100644 test/test-cases/regression/rule-920450.json diff --git a/Makefile.am b/Makefile.am index 3160dcf08d..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 @@ -185,7 +186,6 @@ TESTS+=test/test-cases/regression/request-body-parser-xml-validade-dtd.json TESTS+=test/test-cases/regression/rule-920120.json TESTS+=test/test-cases/regression/rule-920200.json TESTS+=test/test-cases/regression/rule-920274.json -TESTS+=test/test-cases/regression/rule-920450.json TESTS+=test/test-cases/regression/secaction.json TESTS+=test/test-cases/regression/secargumentslimit.json TESTS+=test/test-cases/regression/sec_component_signature.json 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\"" + ] + } +] diff --git a/test/test-cases/regression/rule-920450.json b/test/test-cases/regression/rule-920450.json deleted file mode 100644 index 990e098407..0000000000 --- a/test/test-cases/regression/rule-920450.json +++ /dev/null @@ -1,87 +0,0 @@ -[ - { - "enabled":1, - "version_min":300000, - "title":"OWASP CRS id:920450", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "TRANSLATE": "test" - }, - "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":403 - }, - "rules":[ - "SecRuleEngine On", - "SecRule &TX:restricted_headers \"@eq 0\" \"id:901165,phase:1,pass,nolog,setvar:'tx.restricted_headers=/proxy/ /lock-token/ /content-range/ /translate/ /if/'\"", - "SecRule REQUEST_HEADERS_NAMES \"@rx ^.*$\" \"id:920450,phase:2,capture,block,deny,t:lowercase,setvar:'tx.header_name_%{tx.0}=/%{tx.0}/',chain", - "SecRule TX:/^HEADER_NAME_/ \"@within %{tx.restricted_headers}\" \"\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"OWASP CRS id:920450", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Accept": "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5", - "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", - "Accept-Encoding": "gzip,deflate", - "Accept-Language": "en-us,en;q=0.5", - "Host": "localhost", - "Keep-Alive": "300", - "Proxy-Connection": "keep-alive", - "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv" - }, - "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":200 - }, - "rules":[ - "SecRuleEngine On", - "SecRule &TX:restricted_headers \"@eq 0\" \"id:901165,phase:1,pass,nolog,setvar:'tx.restricted_headers=/proxy/ /lock-token/ /content-range/ /translate/ /if/'\"", - "SecRule REQUEST_HEADERS_NAMES \"@rx ^.*$\" \"id:920450,phase:2,capture,block,deny,t:lowercase,setvar:'tx.header_name_%{tx.0}=/%{tx.0}/',chain", - "SecRule TX:/^HEADER_NAME_/ \"@within %{tx.restricted_headers}\" \"\"" - ] - } -]