mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-13 21:36:00 +03:00
Adds support to custom operator's message in case of a match
This commit is contained in:
parent
ad61838118
commit
0a22f880dd
@ -129,12 +129,8 @@ class RuleMessage {
|
|||||||
std::string msg;
|
std::string msg;
|
||||||
|
|
||||||
msg.append("[client " + std::string(trans->m_clientIpAddress) + "]");
|
msg.append("[client " + std::string(trans->m_clientIpAddress) + "]");
|
||||||
msg.append(" ModSecurity: Warning.");
|
msg.append(" ModSecurity: Warning. ");
|
||||||
msg.append(" Matched \"" + m_match + "\"");
|
msg.append(m_match);
|
||||||
if (trans->m_collections.resolveFirst("MATCHED_VAR_NAME")) {
|
|
||||||
msg.append(" at "
|
|
||||||
+ *trans->m_collections.resolveFirst("MATCHED_VAR_NAME"));
|
|
||||||
}
|
|
||||||
msg.append(" [file \"" + std::string(m_ruleFile) + "\"]");
|
msg.append(" [file \"" + std::string(m_ruleFile) + "\"]");
|
||||||
msg.append(" [line \"" + std::to_string(m_ruleLine) + "\"]");
|
msg.append(" [line \"" + std::to_string(m_ruleLine) + "\"]");
|
||||||
msg.append(" [id \"" + std::to_string(m_ruleId) + "\"]");
|
msg.append(" [id \"" + std::to_string(m_ruleId) + "\"]");
|
||||||
|
@ -28,7 +28,9 @@ class DetectSQLi : public Operator {
|
|||||||
public:
|
public:
|
||||||
/** @ingroup ModSecurity_Operator */
|
/** @ingroup ModSecurity_Operator */
|
||||||
DetectSQLi(std::string op, std::string param, bool negation)
|
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);
|
bool evaluate(Transaction *transaction, const std::string &input);
|
||||||
};
|
};
|
||||||
|
@ -27,7 +27,9 @@ class DetectXSS : public Operator {
|
|||||||
public:
|
public:
|
||||||
/** @ingroup ModSecurity_Operator */
|
/** @ingroup ModSecurity_Operator */
|
||||||
DetectXSS(std::string op, std::string param, bool negation)
|
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);
|
bool evaluate(Transaction *transaction, const std::string &input);
|
||||||
};
|
};
|
||||||
|
@ -50,6 +50,8 @@ class Operator {
|
|||||||
virtual bool evaluate(Transaction *transaction, const std::string &str);
|
virtual bool evaluate(Transaction *transaction, const std::string &str);
|
||||||
static Operator *instantiate(std::string op);
|
static Operator *instantiate(std::string op);
|
||||||
|
|
||||||
|
std::string m_match_message;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool debug(Transaction *transaction, int x, std::string a);
|
bool debug(Transaction *transaction, int x, std::string a);
|
||||||
};
|
};
|
||||||
|
29
src/rule.cc
29
src/rule.cc
@ -401,9 +401,14 @@ bool Rule::evaluate(Transaction *trasn) {
|
|||||||
bool containsPassAction = false;
|
bool containsPassAction = false;
|
||||||
globalRet = true;
|
globalRet = true;
|
||||||
|
|
||||||
ruleMessage->m_match = "Operator `" + this->op->op +
|
if (this->op->m_match_message.empty() == true) {
|
||||||
"' with parameter `" + this->op->param + "' against" \
|
ruleMessage->m_match = "Matched \"Operator `" + this->op->op +
|
||||||
" variable `" + v->m_key + "' (Value: `" + value + "' )";
|
"' 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
|
#ifndef NO_LOGS
|
||||||
trasn->debug(4, "Rule returned 1.");
|
trasn->debug(4, "Rule returned 1.");
|
||||||
trasn->m_collections.storeOrUpdateFirst("MATCHED_VAR",
|
trasn->m_collections.storeOrUpdateFirst("MATCHED_VAR",
|
||||||
@ -419,11 +424,13 @@ bool Rule::evaluate(Transaction *trasn) {
|
|||||||
for (Action *a :
|
for (Action *a :
|
||||||
this->actions_runtime_pos) {
|
this->actions_runtime_pos) {
|
||||||
if (a->isDisruptive() == true) {
|
if (a->isDisruptive() == true) {
|
||||||
containsDisruptive = true;
|
|
||||||
if (a->m_name == "pass") {
|
if (a->m_name == "pass") {
|
||||||
containsPassAction = true;
|
containsPassAction = true;
|
||||||
trasn->debug(4, "Rule contains a `pass' action");
|
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 " \
|
" (rule _does not_ contains a " \
|
||||||
"disruptive action)");
|
"disruptive action)");
|
||||||
#endif
|
#endif
|
||||||
a->evaluate(this, trasn);
|
a->evaluate(this, trasn, ruleMessage);
|
||||||
} else {
|
} else {
|
||||||
#ifndef NO_LOGS
|
#ifndef NO_LOGS
|
||||||
trasn->debug(4, "(SecDefaultAction) " \
|
trasn->debug(4, "(SecDefaultAction) " \
|
||||||
@ -478,7 +485,7 @@ bool Rule::evaluate(Transaction *trasn) {
|
|||||||
"action: " + a->m_name + "!!" \
|
"action: " + a->m_name + "!!" \
|
||||||
+ std::to_string(a->isDisruptive()));
|
+ std::to_string(a->isDisruptive()));
|
||||||
#endif
|
#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) {
|
} else if (globalRet != true) {
|
||||||
#ifndef NO_LOGS
|
#ifndef NO_LOGS
|
||||||
trasn->debug(4, "Rule returned 0.");
|
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())
|
if ((!m_log_message.empty() || !m_log_data.empty())
|
||||||
&& !ruleMessage->m_match.empty()) {
|
&& !ruleMessage->m_match.empty()) {
|
||||||
ruleMessage->m_data = m_log_data;
|
ruleMessage->m_data = m_log_data;
|
||||||
|
ruleMessage->m_message = m_log_message;
|
||||||
trasn->m_rulesMessages.push_back(ruleMessage);
|
trasn->m_rulesMessages.push_back(ruleMessage);
|
||||||
} else {
|
} else {
|
||||||
delete ruleMessage;
|
delete ruleMessage;
|
||||||
|
@ -233,8 +233,9 @@ int Rules::evaluate(int phase, Transaction *transaction) {
|
|||||||
|
|
||||||
int Rules::merge(Driver *from) {
|
int Rules::merge(Driver *from) {
|
||||||
int amount_of_rules = 0;
|
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];
|
std::vector<Rule *> rules = from->rules[i];
|
||||||
|
this->rules[i].empty();
|
||||||
for (int j = 0; j < rules.size(); j++) {
|
for (int j = 0; j < rules.size(); j++) {
|
||||||
amount_of_rules++;
|
amount_of_rules++;
|
||||||
Rule *rule = rules[j];
|
Rule *rule = rules[j];
|
||||||
@ -282,7 +283,7 @@ int Rules::merge(Driver *from) {
|
|||||||
* need to merge anything.
|
* 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];
|
std::vector<Action *> actions = from->defaultActions[i];
|
||||||
this->defaultActions[i].clear();
|
this->defaultActions[i].clear();
|
||||||
for (int j = 0; j < actions.size(); j++) {
|
for (int j = 0; j < actions.size(); j++) {
|
||||||
@ -307,7 +308,7 @@ int Rules::merge(Driver *from) {
|
|||||||
|
|
||||||
int Rules::merge(Rules *from) {
|
int Rules::merge(Rules *from) {
|
||||||
int amount_of_rules = 0;
|
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];
|
std::vector<Rule *> rules = from->rules[i];
|
||||||
for (int j = 0; j < rules.size(); j++) {
|
for (int j = 0; j < rules.size(); j++) {
|
||||||
amount_of_rules++;
|
amount_of_rules++;
|
||||||
@ -365,7 +366,7 @@ void Rules::debug(int level, std::string message) {
|
|||||||
|
|
||||||
void Rules::dump() {
|
void Rules::dump() {
|
||||||
std::cout << "Rules: " << std::endl;
|
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::vector<Rule *> rules = this->rules[i];
|
||||||
std::cout << "Phase: " << std::to_string(i);
|
std::cout << "Phase: " << std::to_string(i);
|
||||||
std::cout << " (" << std::to_string(rules.size());
|
std::cout << " (" << std::to_string(rules.size());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user