Adds support to custom operator's message in case of a match

This commit is contained in:
Felipe Zimmerle 2016-09-12 15:40:03 -03:00
parent ad61838118
commit 0a22f880dd
No known key found for this signature in database
GPG Key ID: E6DFB08CE8B11277
6 changed files with 34 additions and 22 deletions

View File

@ -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) + "\"]");

View File

@ -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);
};

View File

@ -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);
};

View File

@ -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);
};

View File

@ -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;

View File

@ -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<Rule *> 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<Action *> 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<Rule *> 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<Rule *> rules = this->rules[i];
std::cout << "Phase: " << std::to_string(i);
std::cout << " (" << std::to_string(rules.size());