diff --git a/CHANGES b/CHANGES index 803ce72a..d004f779 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,8 @@ v3.0.x - YYYY-MMM-DD (To be released) ------------------------------------- + - Adds capture action to detectSQLi + [Issue #1698 - @zimmerle] - Adds capture action to rbl [Issue #1698 - @zimmerle] - Adds capture action to verifyCC diff --git a/Makefile.am b/Makefile.am index f0a1fcd6..208cfd14 100644 --- a/Makefile.am +++ b/Makefile.am @@ -138,6 +138,7 @@ TESTS+=test/test-cases/regression/issue-960.json TESTS+=test/test-cases/regression/misc.json TESTS+=test/test-cases/regression/misc-variable-under-quotes.json TESTS+=test/test-cases/regression/offset-variable.json +TESTS+=test/test-cases/regression/operator-detectsqli.json TESTS+=test/test-cases/regression/operator-fuzzyhash.json TESTS+=test/test-cases/regression/operator-inpectFile.json TESTS+=test/test-cases/regression/operator-ipMatchFromFile.json diff --git a/src/operators/detect_sqli.cc b/src/operators/detect_sqli.cc index a5c4350b..acf87cbd 100644 --- a/src/operators/detect_sqli.cc +++ b/src/operators/detect_sqli.cc @@ -25,25 +25,35 @@ namespace modsecurity { namespace operators { -bool DetectSQLi::evaluate(Transaction *transaction, const std::string &input) { +bool DetectSQLi::evaluate(Transaction *t, Rule *rule, + const std::string& input, std::shared_ptr ruleMessage) { char fingerprint[8]; int issqli; issqli = libinjection_sqli(input.c_str(), input.length(), fingerprint); if (issqli) { - if (transaction) { - transaction->m_matched.push_back(fingerprint); + if (t) { + t->m_matched.push_back(fingerprint); #ifndef NO_LOGS - transaction->debug(4, "detected SQLi using libinjection with " \ + t->debug(4, "detected SQLi using libinjection with " \ "fingerprint '" + std::string(fingerprint) + "' at: '" + input + "'"); #endif + if (rule && t + && rule->getActionsByName("capture").size() > 0) { + t->m_collections.m_tx_collection->storeOrUpdateFirst( + "0", std::string(fingerprint)); +#ifndef NO_LOGS + t->debug(7, "Added DetectSQLi match TX.0: " + \ + std::string(fingerprint)); +#endif + } } } else { - if (transaction) { + if (t) { #ifndef NO_LOGS - transaction->debug(9, "detected SQLi: not able to find an " \ + t->debug(9, "detected SQLi: not able to find an " \ "inject on '" + input + "'"); #endif } diff --git a/src/operators/detect_sqli.h b/src/operators/detect_sqli.h index 85dc2664..9621576c 100644 --- a/src/operators/detect_sqli.h +++ b/src/operators/detect_sqli.h @@ -32,7 +32,9 @@ class DetectSQLi : public Operator { m_match_message.assign("detected SQLi using libinjection."); } - bool evaluate(Transaction *transaction, const std::string &input); + bool evaluate(Transaction *t, Rule *rule, + const std::string& input, + std::shared_ptr ruleMessage) override; }; } // namespace operators diff --git a/test/test-cases/regression/operator-detectsqli.json b/test/test-cases/regression/operator-detectsqli.json new file mode 100644 index 00000000..e2e33c90 --- /dev/null +++ b/test/test-cases/regression/operator-detectsqli.json @@ -0,0 +1,46 @@ +[ + { + "enabled":1, + "version_min":300000, + "title":"Testing Operator :: @detectSQLi", + "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":"POST", + "body": [ + "param1=ascii(substring(version() from 1 for 1))¶m2=value2" + ] + }, + "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":"Added DetectSQLi match TX.0: f\\(f\\(f" + }, + "rules":[ + "SecRuleEngine On", + "SecRule ARGS \"@detectSQLi\" \"id:1,phase:2,capture,pass,t:trim\"" + ] + } +]