diff --git a/src/actions/action.h b/src/actions/action.h index 3b9deda6..47ae759c 100644 --- a/src/actions/action.h +++ b/src/actions/action.h @@ -87,6 +87,7 @@ class Action { virtual std::string evaluate(std::string exp, Assay *assay); virtual bool evaluate(Rule *rule, Assay *assay); + virtual bool init(std::string *error) { return true; } static Action *instantiate(const std::string& name); diff --git a/src/actions/rule_id.cc b/src/actions/rule_id.cc index 8ebe4707..7de4311b 100644 --- a/src/actions/rule_id.cc +++ b/src/actions/rule_id.cc @@ -24,21 +24,33 @@ namespace ModSecurity { namespace actions { -RuleId::RuleId(std::string action) - : Action(action) { - this->action_kind = ConfigurationKind; +bool RuleId::init(std::string *error) { std::string a = action; - a.erase(0, 3); - if (a.at(0) == '\'') { - a.erase(0, 1); - a.pop_back(); - } - this->rule_id = std::stod(a); + + try { + a.erase(0, 3); + if (a.at(0) == '\'') { + a.erase(0, 1); + a.pop_back(); + } + m_ruleId = std::stod(a); + } catch (...) { + m_ruleId = 0; + error->assign("The input \"" + a + "\" does not seems to be a valid rule id."); + return false; } + std::ostringstream oss; + oss << std::setprecision(40) << m_ruleId; + if (a != oss.str() || m_ruleId < 0) { + error->assign("The input \"" + a + "\" does not seems to be a valid rule id."); + return false; + } + return true; +} bool RuleId::evaluate(Rule *rule, Assay *assay) { - rule->rule_id = this->rule_id; + rule->rule_id = m_ruleId; return true; } diff --git a/src/actions/rule_id.h b/src/actions/rule_id.h index d24f1a88..00ad6427 100644 --- a/src/actions/rule_id.h +++ b/src/actions/rule_id.h @@ -32,10 +32,14 @@ namespace actions { class RuleId : public Action { public: - explicit RuleId(std::string action); + explicit RuleId(std::string action) + : Action(action, ConfigurationKind) { } + bool init(std::string *error) override; bool evaluate(Rule *rule, Assay *assay) override; - double rule_id; + +private: + double m_ruleId; }; } // namespace actions diff --git a/src/parser/seclang-parser.yy b/src/parser/seclang-parser.yy index 16d7c1bc..9894bb2a 100644 --- a/src/parser/seclang-parser.yy +++ b/src/parser/seclang-parser.yy @@ -604,7 +604,13 @@ var: act: ACTION { + std::string error; $$ = Action::instantiate($1); + + if ($$->init(&error) == false) { + driver.parserError << error; + YYERROR; + } } | TRANSFORMATION { diff --git a/test/test-cases/regression/action-id.json b/test/test-cases/regression/action-id.json new file mode 100644 index 00000000..99311b5f --- /dev/null +++ b/test/test-cases/regression/action-id.json @@ -0,0 +1,278 @@ +[ + { + "enabled":1, + "version_min":300000, + "title":"Testing Action :: id (1/6)", + "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":"/", + "protocol":"POST", + "body": [ + "param1=value1¶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":{ + "parser_error": "The input \"111111111111222222222222222222222222222333333333333333333333333333444444444444444444444444444444555555555555555555555555666666666666666666666666666666666666666666\" does not seems to be a valid rule id." + }, + "rules":[ + "SecRuleEngine On", + "SecDebugLog \/tmp\/modsec_debug.log", + "SecDebugLogLevel 9", + "SecRule ARGS \"@rx (value1)\" \"id:111111111111222222222222222222222222222333333333333333333333333333444444444444444444444444444444555555555555555555555555666666666666666666666666666666666666666666,phase:2,pass,t:trim\"" + ] + }, + { + "enabled":1, + "version_min":300000, + "title":"Testing Action :: id (2/6)", + "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":"/", + "protocol":"POST", + "body": [ + "param1=value1¶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":{ + "parser_error": "Rules error. File: action-id.json. Line: 4. Column: 31. id:-1" + }, + "rules":[ + "SecRuleEngine On", + "SecDebugLog \/tmp\/modsec_debug.log", + "SecDebugLogLevel 9", + "SecRule ARGS \"@rx (value1)\" \"id:-1,phase:2,pass,t:trim\"" + ] + }, + { + "enabled":1, + "version_min":300000, + "title":"Testing Action :: id (3/6)", + "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":"/", + "protocol":"POST", + "body": [ + "param1=value1¶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": " trim: \"value2\"" + }, + "rules":[ + "SecRuleEngine On", + "SecDebugLog \/tmp\/modsec_debug.log", + "SecDebugLogLevel 9", + "SecRule ARGS \"@rx (value1)\" \"id:1,phase:2,pass,t:trim\"" + ] + }, + { + "enabled":1, + "version_min":300000, + "title":"Testing Action :: id (4/6)", + "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":"/", + "protocol":"POST", + "body": [ + "param1=value1¶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": " trim: \"value2\"" + }, + "rules":[ + "SecRuleEngine On", + "SecDebugLog \/tmp\/modsec_debug.log", + "SecDebugLogLevel 9", + "SecRule ARGS \"@rx (value1)\" \"id:'1',phase:2,pass,t:trim\"" + ] + }, + { + "enabled":1, + "version_min":300000, + "title":"Testing Action :: id (5/6)", + "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":"/", + "protocol":"POST", + "body": [ + "param1=value1¶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":{ + "parser_error": "Rules error. File: action-id.json. Line: 4. Column: 31. id:'1" + }, + "rules":[ + "SecRuleEngine On", + "SecDebugLog \/tmp\/modsec_debug.log", + "SecDebugLogLevel 9", + "SecRule ARGS \"@rx (value1)\" \"id:'1,phase:2,pass,t:trim\"" + ] + }, + { + "enabled":1, + "version_min":300000, + "title":"Testing Action :: id (6/6)", + "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":"/", + "protocol":"POST", + "body": [ + "param1=value1¶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": "trim: \"value2\"" + }, + "rules":[ + "SecRuleEngine On", + "SecDebugLog \/tmp\/modsec_debug.log", + "SecDebugLogLevel 9", + "SecRule ARGS \"@rx (value1)\" \"id:1',phase:2,pass,t:trim\"" + ] + } +] \ No newline at end of file