diff --git a/headers/modsecurity/rule.h b/headers/modsecurity/rule.h index 55214d01..1b08280a 100644 --- a/headers/modsecurity/rule.h +++ b/headers/modsecurity/rule.h @@ -129,12 +129,8 @@ class RuleMessage { std::string msg; msg.append("[client " + std::string(trans->m_clientIpAddress) + "]"); - msg.append(" ModSecurity: Warning."); - msg.append(" Matched \"" + m_match + "\""); - if (trans->m_collections.resolveFirst("MATCHED_VAR_NAME")) { - msg.append(" at " - + *trans->m_collections.resolveFirst("MATCHED_VAR_NAME")); - } + msg.append(" ModSecurity: Warning. "); + msg.append(m_match); msg.append(" [file \"" + std::string(m_ruleFile) + "\"]"); msg.append(" [line \"" + std::to_string(m_ruleLine) + "\"]"); msg.append(" [id \"" + std::to_string(m_ruleId) + "\"]"); diff --git a/src/operators/detect_sqli.h b/src/operators/detect_sqli.h index d4f9df92..5d79ee8f 100644 --- a/src/operators/detect_sqli.h +++ b/src/operators/detect_sqli.h @@ -28,7 +28,9 @@ class DetectSQLi : public Operator { public: /** @ingroup ModSecurity_Operator */ DetectSQLi(std::string op, std::string param, bool negation) - : Operator(op, param, negation) { } + : Operator(op, param, negation) { + m_match_message.assign("detected SQLi using libinjection."); + } bool evaluate(Transaction *transaction, const std::string &input); }; diff --git a/src/operators/detect_xss.h b/src/operators/detect_xss.h index 5d27c20c..9b2e4f01 100644 --- a/src/operators/detect_xss.h +++ b/src/operators/detect_xss.h @@ -27,7 +27,9 @@ class DetectXSS : public Operator { public: /** @ingroup ModSecurity_Operator */ DetectXSS(std::string op, std::string param, bool negation) - : Operator(op, param, negation) { } + : Operator(op, param, negation) { + m_match_message.assign("detected XSS using libinjection."); + } bool evaluate(Transaction *transaction, const std::string &input); }; diff --git a/src/operators/operator.h b/src/operators/operator.h index ae267f44..56450564 100644 --- a/src/operators/operator.h +++ b/src/operators/operator.h @@ -50,6 +50,8 @@ class Operator { virtual bool evaluate(Transaction *transaction, const std::string &str); static Operator *instantiate(std::string op); + std::string m_match_message; + protected: bool debug(Transaction *transaction, int x, std::string a); }; diff --git a/src/rule.cc b/src/rule.cc index 39f58366..615cfaff 100644 --- a/src/rule.cc +++ b/src/rule.cc @@ -401,9 +401,14 @@ bool Rule::evaluate(Transaction *trasn) { bool containsPassAction = false; globalRet = true; - ruleMessage->m_match = "Operator `" + this->op->op + - "' with parameter `" + this->op->param + "' against" \ - " variable `" + v->m_key + "' (Value: `" + value + "' )"; + if (this->op->m_match_message.empty() == true) { + ruleMessage->m_match = "Matched \"Operator `" + this->op->op + + "' with parameter `" + this->op->param + "' against" \ + " variable `" + v->m_key + "' (Value: `" + value + "' ) " + + "\" at " + v->m_key; + } else { + ruleMessage->m_match = this->op->m_match_message; + } #ifndef NO_LOGS trasn->debug(4, "Rule returned 1."); trasn->m_collections.storeOrUpdateFirst("MATCHED_VAR", @@ -419,11 +424,13 @@ bool Rule::evaluate(Transaction *trasn) { for (Action *a : this->actions_runtime_pos) { if (a->isDisruptive() == true) { - containsDisruptive = true; if (a->m_name == "pass") { containsPassAction = true; trasn->debug(4, "Rule contains a `pass' action"); + } else { + containsDisruptive = true; } + } } @@ -461,7 +468,7 @@ bool Rule::evaluate(Transaction *trasn) { " (rule _does not_ contains a " \ "disruptive action)"); #endif - a->evaluate(this, trasn); + a->evaluate(this, trasn, ruleMessage); } else { #ifndef NO_LOGS trasn->debug(4, "(SecDefaultAction) " \ @@ -478,7 +485,7 @@ bool Rule::evaluate(Transaction *trasn) { "action: " + a->m_name + "!!" \ + std::to_string(a->isDisruptive())); #endif - a->evaluate(this, trasn); + a->evaluate(this, trasn, ruleMessage); } } } @@ -519,6 +526,11 @@ bool Rule::evaluate(Transaction *trasn) { } } } + if (ruleMessage->m_saveMessage == true) { + ruleMessage->m_message = m_log_message; + trasn->debug(4, "Saving on the server log: " + ruleMessage->errorLog(trasn)); + trasn->serverLog(ruleMessage->errorLog(trasn)); + } } else if (globalRet != true) { #ifndef NO_LOGS trasn->debug(4, "Rule returned 0."); @@ -537,13 +549,10 @@ bool Rule::evaluate(Transaction *trasn) { } } - if (ruleMessage->m_saveMessage == true) { - trasn->serverLog(ruleMessage->errorLog(trasn)); - } - if ((!m_log_message.empty() || !m_log_data.empty()) && !ruleMessage->m_match.empty()) { ruleMessage->m_data = m_log_data; + ruleMessage->m_message = m_log_message; trasn->m_rulesMessages.push_back(ruleMessage); } else { delete ruleMessage; diff --git a/src/rules.cc b/src/rules.cc index 6baacc10..ab84137d 100644 --- a/src/rules.cc +++ b/src/rules.cc @@ -233,8 +233,9 @@ int Rules::evaluate(int phase, Transaction *transaction) { int Rules::merge(Driver *from) { int amount_of_rules = 0; - for (int i = 0; i < ModSecurity::Phases::NUMBER_OF_PHASES; i++) { + for (int i = 0; i <= ModSecurity::Phases::NUMBER_OF_PHASES; i++) { std::vector rules = from->rules[i]; + this->rules[i].empty(); for (int j = 0; j < rules.size(); j++) { amount_of_rules++; Rule *rule = rules[j]; @@ -282,7 +283,7 @@ int Rules::merge(Driver *from) { * need to merge anything. * */ - for (int i = 0; i < ModSecurity::Phases::NUMBER_OF_PHASES; i++) { + for (int i = 0; i <= ModSecurity::Phases::NUMBER_OF_PHASES; i++) { std::vector actions = from->defaultActions[i]; this->defaultActions[i].clear(); for (int j = 0; j < actions.size(); j++) { @@ -307,7 +308,7 @@ int Rules::merge(Driver *from) { int Rules::merge(Rules *from) { int amount_of_rules = 0; - for (int i = 0; i < ModSecurity::Phases::NUMBER_OF_PHASES; i++) { + for (int i = 0; i <= ModSecurity::Phases::NUMBER_OF_PHASES; i++) { std::vector rules = from->rules[i]; for (int j = 0; j < rules.size(); j++) { amount_of_rules++; @@ -365,7 +366,7 @@ void Rules::debug(int level, std::string message) { void Rules::dump() { std::cout << "Rules: " << std::endl; - for (int i = 0; i < ModSecurity::Phases::NUMBER_OF_PHASES; i++) { + for (int i = 0; i <= ModSecurity::Phases::NUMBER_OF_PHASES; i++) { std::vector rules = this->rules[i]; std::cout << "Phase: " << std::to_string(i); std::cout << " (" << std::to_string(rules.size());