Refactoring on the operators: negation is now being handled globally

Other minors changes were also made, including adding the prefix `m_'
to all the members of the class.
This commit is contained in:
Felipe Zimmerle 2016-10-19 10:23:03 -03:00
parent 28a44b966a
commit 8757840bc3
No known key found for this signature in database
GPG Key ID: E6DFB08CE8B11277
36 changed files with 88 additions and 138 deletions

View File

@ -27,7 +27,7 @@ namespace operators {
bool BeginsWith::evaluate(Transaction *transaction, const std::string &str) { bool BeginsWith::evaluate(Transaction *transaction, const std::string &str) {
bool ret = false; bool ret = false;
std::string p = MacroExpansion::expand(param, transaction); std::string p = MacroExpansion::expand(m_param, transaction);
if (str.size() < p.size()) { if (str.size() < p.size()) {
ret = false; ret = false;
@ -35,10 +35,6 @@ bool BeginsWith::evaluate(Transaction *transaction, const std::string &str) {
ret = true; ret = true;
} }
if (negation) {
return !ret;
}
return ret; return ret;
} }

View File

@ -23,17 +23,13 @@ namespace modsecurity {
namespace operators { namespace operators {
bool Contains::evaluate(Transaction *transaction, const std::string &input) { bool Contains::evaluate(Transaction *transaction, const std::string &input) {
std::string p = MacroExpansion::expand(param, transaction); std::string p = MacroExpansion::expand(m_param, transaction);
bool contains = input.find(p) != std::string::npos; bool contains = input.find(p) != std::string::npos;
if (contains && transaction) { if (contains && transaction) {
transaction->m_matched.push_back(p); transaction->m_matched.push_back(p);
} }
if (negation) {
return !contains;
}
return contains; return contains;
} }

View File

@ -38,7 +38,7 @@ bool ContainsWord::acceptableChar(const std::string& a, size_t pos) {
bool ContainsWord::evaluate(Transaction *transaction, bool ContainsWord::evaluate(Transaction *transaction,
const std::string& input) { const std::string& input) {
std::string paramTarget = MacroExpansion::expand(param, transaction); std::string paramTarget = MacroExpansion::expand(m_param, transaction);
if (paramTarget.empty()) { if (paramTarget.empty()) {
return true; return true;

View File

@ -49,10 +49,6 @@ bool DetectSQLi::evaluate(Transaction *transaction, const std::string &input) {
} }
} }
if (negation) {
return issqli == 0;
}
return issqli != 0; return issqli != 0;
} }

View File

@ -41,10 +41,6 @@ bool DetectXSS::evaluate(Transaction *transaction, const std::string &input) {
#endif #endif
} }
if (negation) {
return is_xss == 0;
}
return is_xss != 0; return is_xss != 0;
} }

View File

@ -26,17 +26,13 @@ namespace operators {
bool EndsWith::evaluate(Transaction *transaction, const std::string &input) { bool EndsWith::evaluate(Transaction *transaction, const std::string &input) {
bool ret = false; bool ret = false;
std::string p = MacroExpansion::expand(param, transaction); std::string p = MacroExpansion::expand(m_param, transaction);
if (input.length() >= p.length()) { if (input.length() >= p.length()) {
ret = (0 == input.compare(input.length() - p.length(), ret = (0 == input.compare(input.length() - p.length(),
p.length(), p)); p.length(), p));
} }
if (negation) {
return !ret;
}
return ret; return ret;
} }

View File

@ -28,7 +28,7 @@ bool Eq::evaluate(Transaction *transaction, const std::string &input) {
int p = 0; int p = 0;
int i = 0; int i = 0;
bool eq = false; bool eq = false;
std::string pt = MacroExpansion::expand(param, transaction); std::string pt = MacroExpansion::expand(m_param, transaction);
try { try {
p = std::stoi(pt); p = std::stoi(pt);
@ -43,10 +43,6 @@ bool Eq::evaluate(Transaction *transaction, const std::string &input) {
eq = p == i; eq = p == i;
if (negation) {
return !eq;
}
return eq; return eq;
} }

View File

@ -34,8 +34,8 @@ bool FuzzyHash::evaluate(Transaction *transaction, const std::string &str) {
FuzzyHash::FuzzyHash(std::string op, std::string param, FuzzyHash::FuzzyHash(std::string op, std::string param,
bool negation) bool negation)
: Operator() { : Operator() {
this->op = op; this->m_op = op;
this->param = param; this->m_param = param;
} }
} // namespace operators } // namespace operators

View File

@ -24,15 +24,11 @@ namespace modsecurity {
namespace operators { namespace operators {
bool Ge::evaluate(Transaction *transaction, const std::string &input) { bool Ge::evaluate(Transaction *transaction, const std::string &input) {
std::string p = MacroExpansion::expand(param, transaction); std::string p = MacroExpansion::expand(m_param, transaction);
std::string i = MacroExpansion::expand(input, transaction); std::string i = MacroExpansion::expand(input, transaction);
bool ge = atoll(i.c_str()) >= atoll(p.c_str()); bool ge = atoll(i.c_str()) >= atoll(p.c_str());
if (negation) {
return !ge;
}
return ge; return ge;
} }

View File

@ -96,8 +96,8 @@ bool GeoLookup::evaluate(Transaction *trans, const std::string &exp) {
GeoLookup::GeoLookup(std::string op, std::string param, GeoLookup::GeoLookup(std::string op, std::string param,
bool negation) bool negation)
: Operator() { : Operator() {
this->op = op; this->m_op = op;
this->param = param; this->m_param = param;
} }
} // namespace operators } // namespace operators

View File

@ -34,8 +34,8 @@ bool GsbLookup::evaluate(Transaction *transaction, const std::string &str) {
GsbLookup::GsbLookup(std::string op, std::string param, GsbLookup::GsbLookup(std::string op, std::string param,
bool negation) bool negation)
: Operator() { : Operator() {
this->op = op; this->m_op = op;
this->param = param; this->m_param = param;
} }
} // namespace operators } // namespace operators

View File

@ -24,14 +24,10 @@ namespace modsecurity {
namespace operators { namespace operators {
bool Gt::evaluate(Transaction *transaction, const std::string &input) { bool Gt::evaluate(Transaction *transaction, const std::string &input) {
std::string p = MacroExpansion::expand(param, transaction); std::string p = MacroExpansion::expand(m_param, transaction);
bool gt = atoll(input.c_str()) > atoll(p.c_str()); bool gt = atoll(input.c_str()) > atoll(p.c_str());
if (negation) {
return !gt;
}
return gt; return gt;
} }

View File

@ -34,8 +34,8 @@ bool InspectFile::evaluate(Transaction *transaction, const std::string &str) {
InspectFile::InspectFile(std::string op, std::string param, InspectFile::InspectFile(std::string op, std::string param,
bool negation) bool negation)
: Operator() { : Operator() {
this->op = op; this->m_op = op;
this->param = param; this->m_param = param;
} }
} // namespace operators } // namespace operators

View File

@ -27,7 +27,7 @@ namespace operators {
bool IpMatch::init(const std::string &file, std::string *error) { bool IpMatch::init(const std::string &file, std::string *error) {
std::string e(""); std::string e("");
bool res = m_tree.addFromBuffer(param, &e); bool res = m_tree.addFromBuffer(m_param, &e);
if (res == false) { if (res == false) {
error->assign(e); error->assign(e);

View File

@ -30,10 +30,10 @@ bool IpMatchFromFile::init(const std::string &file,
std::string e(""); std::string e("");
bool res = false; bool res = false;
if (param.compare(0, 8, "https://") == 0) { if (m_param.compare(0, 8, "https://") == 0) {
res = m_tree.addFromUrl(param, &e); res = m_tree.addFromUrl(m_param, &e);
} else { } else {
res = m_tree.addFromFile(param, &e); res = m_tree.addFromFile(m_param, &e);
} }
if (res == false) { if (res == false) {

View File

@ -24,14 +24,10 @@ namespace modsecurity {
namespace operators { namespace operators {
bool Le::evaluate(Transaction *transaction, const std::string &input) { bool Le::evaluate(Transaction *transaction, const std::string &input) {
std::string p = MacroExpansion::expand(param, transaction); std::string p = MacroExpansion::expand(m_param, transaction);
bool le = atoll(input.c_str()) <= atoll(p.c_str()); bool le = atoll(input.c_str()) <= atoll(p.c_str());
if (negation) {
return !le;
}
return le; return le;
} }

View File

@ -24,14 +24,10 @@ namespace modsecurity {
namespace operators { namespace operators {
bool Lt::evaluate(Transaction *transaction, const std::string &input) { bool Lt::evaluate(Transaction *transaction, const std::string &input) {
std::string p = MacroExpansion::expand(param, transaction); std::string p = MacroExpansion::expand(m_param, transaction);
bool lt = atoll(input.c_str()) < atoll(p.c_str()); bool lt = atoll(input.c_str()) < atoll(p.c_str());
if (negation) {
return !lt;
}
return lt; return lt;
} }

View File

@ -75,13 +75,25 @@ bool Operator::debug(Transaction *transaction, int x, std::string a) {
} }
bool Operator::evaluateInternal(Transaction *transaction,
const std::string& a) {
bool res = evaluate(transaction, a);
if (m_negation) {
return !res;
}
return res;
}
bool Operator::evaluate(Transaction *transaction, const std::string& a) { bool Operator::evaluate(Transaction *transaction, const std::string& a) {
#ifndef NO_LOGS #ifndef NO_LOGS
if (transaction) { if (transaction) {
transaction->debug(2, "Operator: " + this->op + \ transaction->debug(2, "Operator: " + this->m_op + \
" is not implemented or malfunctioning."); " is not implemented or malfunctioning.");
} else { } else {
std::cerr << "Operator: " + this->op + \ std::cerr << "Operator: " + this->m_op + \
" is not implemented or malfunctioning."; " is not implemented or malfunctioning.";
} }
#endif #endif
@ -183,4 +195,3 @@ Operator *Operator::instantiate(std::string op_string) {
} // namespace operators } // namespace operators
} // namespace modsecurity } // namespace modsecurity

View File

@ -30,27 +30,30 @@ class Operator {
public: public:
/** @ingroup ModSecurity_Operator */ /** @ingroup ModSecurity_Operator */
Operator() Operator()
: op(""), : m_match_message(""),
param(""), m_negation(false),
negation(false) { } m_op(""),
m_param("") { }
Operator(std::string op, std::string param, bool negation) Operator(std::string op, std::string param, bool negation)
: op(op), : m_match_message(""),
param(param), m_negation(negation),
negation(negation) { } m_op(op),
m_param(param) { }
virtual ~Operator() { } virtual ~Operator() { }
std::string op; static Operator *instantiate(std::string opName);
std::string param;
bool negation;
virtual bool init(const std::string &file, std::string *error) { virtual bool init(const std::string &arg, std::string *error) {
return true; return true;
} }
bool evaluateInternal(Transaction *t, const std::string& a);
virtual bool evaluate(Transaction *transaction, const std::string &str); virtual bool evaluate(Transaction *transaction, const std::string &str);
static Operator *instantiate(std::string op);
bool m_negation;
std::string m_match_message; std::string m_match_message;
std::string m_op;
std::string m_param;
protected: protected:
bool debug(Transaction *transaction, int x, std::string a); bool debug(Transaction *transaction, int x, std::string a);

View File

@ -109,11 +109,11 @@ bool Pm::init(const std::string &file, std::string *error) {
std::istringstream *iss; std::istringstream *iss;
const char *err = NULL; const char *err = NULL;
replaceAll(param, "\\", "\\\\"); replaceAll(m_param, "\\", "\\\\");
char *content = parse_pm_content(param.c_str(), param.length(), &err); char *content = parse_pm_content(m_param.c_str(), m_param.length(), &err);
if (content == NULL) { if (content == NULL) {
iss = new std::istringstream(param); iss = new std::istringstream(m_param);
} else { } else {
iss = new std::istringstream(content); iss = new std::istringstream(content);
} }

View File

@ -28,20 +28,20 @@ namespace operators {
bool PmFromFile::init(const std::string &config, std::string *error) { bool PmFromFile::init(const std::string &config, std::string *error) {
std::istream *iss; std::istream *iss;
if (param.compare(0, 8, "https://") == 0) { if (m_param.compare(0, 8, "https://") == 0) {
Utils::HttpsClient client; Utils::HttpsClient client;
bool ret = client.download(param); bool ret = client.download(m_param);
if (ret == false) { if (ret == false) {
error->assign(client.error); error->assign(client.error);
return false; return false;
} }
iss = new std::stringstream(client.content); iss = new std::stringstream(client.content);
} else { } else {
std::string resource = find_resource(param, config); std::string resource = find_resource(m_param, config);
iss = new std::ifstream(resource, std::ios::in); iss = new std::ifstream(resource, std::ios::in);
if (((std::ifstream *)iss)->is_open() == false) { if (((std::ifstream *)iss)->is_open() == false) {
error->assign("Failed to open file: " + param); error->assign("Failed to open file: " + m_param);
delete iss; delete iss;
return false; return false;
} }

View File

@ -33,8 +33,8 @@ bool Rsub::evaluate(Transaction *transaction, const std::string &str) {
Rsub::Rsub(std::string op, std::string param, bool negation) Rsub::Rsub(std::string op, std::string param, bool negation)
: Operator() { : Operator() {
this->op = op; this->m_op = op;
this->param = param; this->m_param = param;
} }
} // namespace operators } // namespace operators

View File

@ -22,13 +22,9 @@ namespace modsecurity {
namespace operators { namespace operators {
bool StrEq::evaluate(Transaction *transaction, const std::string &str) { bool StrEq::evaluate(Transaction *transaction, const std::string &str) {
std::string p = MacroExpansion::expand(param, transaction); std::string p = MacroExpansion::expand(m_param, transaction);
bool eq = !p.compare(str); bool eq = !p.compare(str);
if (negation) {
return !eq;
}
return eq; return eq;
} }

View File

@ -25,13 +25,9 @@ namespace operators {
bool StrMatch::evaluate(Transaction *transaction, const std::string &input) { bool StrMatch::evaluate(Transaction *transaction, const std::string &input) {
std::string p = MacroExpansion::expand(param, transaction); std::string p = MacroExpansion::expand(m_param, transaction);
bool ret = input.find(p) != std::string::npos; bool ret = input.find(p) != std::string::npos;
if (negation) {
return !ret;
}
return ret; return ret;
} }

View File

@ -22,10 +22,6 @@ bool UnconditionalMatch::evaluate(Transaction *transaction,
const std::string &input) { const std::string &input) {
bool contains = true; bool contains = true;
if (negation) {
return !contains;
}
return contains; return contains;
} }

View File

@ -85,22 +85,22 @@ bool ValidateByteRange::getRange(const std::string &rangeRepresentation,
bool ValidateByteRange::init(const std::string &file, bool ValidateByteRange::init(const std::string &file,
std::string *error) { std::string *error) {
size_t pos = param.find_first_of(","); size_t pos = m_param.find_first_of(",");
if (pos == std::string::npos) { if (pos == std::string::npos) {
getRange(param, error); getRange(m_param, error);
} else { } else {
getRange(std::string(param, 0, pos), error); getRange(std::string(m_param, 0, pos), error);
} }
while (pos != std::string::npos) { while (pos != std::string::npos) {
size_t next_pos = param.find_first_of(",", pos + 1); size_t next_pos = m_param.find_first_of(",", pos + 1);
if (next_pos == std::string::npos) { if (next_pos == std::string::npos) {
getRange(std::string(param, pos + 1, param.length() - getRange(std::string(m_param, pos + 1, m_param.length() -
(pos + 1)), error); (pos + 1)), error);
} else { } else {
getRange(std::string(param, pos + 1, next_pos), error); getRange(std::string(m_param, pos + 1, next_pos), error);
} }
pos = next_pos; pos = next_pos;
} }
@ -128,10 +128,6 @@ bool ValidateByteRange::evaluate(Transaction *transaction,
// debug(9, "Found %d byte(s) in %s outside range: %s.", // debug(9, "Found %d byte(s) in %s outside range: %s.",
// count, var->name, rule->op_param); // count, var->name, rule->op_param);
if (negation) {
return !ret;
}
return ret; return ret;
} }

View File

@ -26,9 +26,9 @@ namespace operators {
bool ValidateDTD::init(const std::string &file, std::string *error) { bool ValidateDTD::init(const std::string &file, std::string *error) {
m_resource = find_resource(param, file); m_resource = find_resource(m_param, file);
if (m_resource == "") { if (m_resource == "") {
error->assign("XML: File not found: " + param + "."); error->assign("XML: File not found: " + m_param + ".");
return false; return false;
} }

View File

@ -33,8 +33,8 @@ bool ValidateHash::evaluate(Transaction *transaction, const std::string &str) {
ValidateHash::ValidateHash(std::string op, std::string param, bool negation) ValidateHash::ValidateHash(std::string op, std::string param, bool negation)
: Operator() { : Operator() {
this->op = op; this->m_op = op;
this->param = param; this->m_param = param;
} }
} // namespace operators } // namespace operators

View File

@ -26,9 +26,9 @@ namespace modsecurity {
namespace operators { namespace operators {
bool ValidateSchema::init(const std::string &file, std::string *error) { bool ValidateSchema::init(const std::string &file, std::string *error) {
m_resource = find_resource(param, file); m_resource = find_resource(m_param, file);
if (m_resource == "") { if (m_resource == "") {
error->assign("XML: File not found: " + param + "."); error->assign("XML: File not found: " + m_param + ".");
return false; return false;
} }

View File

@ -115,10 +115,6 @@ bool ValidateUrlEncoding::evaluate(Transaction *transaction,
break; break;
} }
if (negation) {
return !res;
}
return res; return res;
} }

View File

@ -93,7 +93,7 @@ bool VerifyCC::init(const std::string &param2, std::string *error) {
const char *errptr = NULL; const char *errptr = NULL;
int erroffset = 0; int erroffset = 0;
m_pc = pcre_compile(param.c_str(), PCRE_DOTALL|PCRE_MULTILINE, m_pc = pcre_compile(m_param.c_str(), PCRE_DOTALL|PCRE_MULTILINE,
&errptr, &erroffset, NULL); &errptr, &erroffset, NULL);
if (m_pc == NULL) { if (m_pc == NULL) {
error->assign(errptr); error->assign(errptr);
@ -143,7 +143,7 @@ bool VerifyCC::evaluate(Transaction *transaction, const std::string &i) {
if (is_cc) { if (is_cc) {
if (transaction) { if (transaction) {
#ifndef NO_LOGS #ifndef NO_LOGS
transaction->debug(9, "CC# match \"" + param + transaction->debug(9, "CC# match \"" + m_param +
"\" at " + i + ". [offset " + "\" at " + i + ". [offset " +
std::to_string(offset) + "]"); std::to_string(offset) + "]");
#endif #endif
@ -159,3 +159,4 @@ bool VerifyCC::evaluate(Transaction *transaction, const std::string &i) {
} // namespace operators } // namespace operators
} // namespace modsecurity } // namespace modsecurity

View File

@ -33,8 +33,8 @@ bool VerifyCPF::evaluate(Transaction *transaction, const std::string &str) {
VerifyCPF::VerifyCPF(std::string op, std::string param, bool negation) VerifyCPF::VerifyCPF(std::string op, std::string param, bool negation)
: Operator() { : Operator() {
this->op = op; this->m_op = op;
this->param = param; this->m_param = param;
} }
} // namespace operators } // namespace operators

View File

@ -32,8 +32,8 @@ bool VerifySSN::evaluate(Transaction *transaction, const std::string &str) {
VerifySSN::VerifySSN(std::string op, std::string param, bool negation) VerifySSN::VerifySSN(std::string op, std::string param, bool negation)
: Operator() { : Operator() {
this->op = op; this->m_op = op;
this->param = param; this->m_param = param;
} }
} // namespace operators } // namespace operators

View File

@ -26,7 +26,7 @@ namespace operators {
bool Within::evaluate(Transaction *transaction, const std::string &str) { bool Within::evaluate(Transaction *transaction, const std::string &str) {
bool res = false; bool res = false;
std::string paramTarget = MacroExpansion::expand(param, transaction); std::string paramTarget = MacroExpansion::expand(m_param, transaction);
if (str.empty()) { if (str.empty()) {
return true; return true;
@ -34,11 +34,6 @@ bool Within::evaluate(Transaction *transaction, const std::string &str) {
res = paramTarget.find(str) != std::string::npos; res = paramTarget.find(str) != std::string::npos;
if (negation) {
return !res;
}
return res; return res;
} }

View File

@ -286,16 +286,16 @@ bool Rule::evaluate(Transaction *trasn) {
ruleMessage = new modsecurity::RuleMessage(this, m_log_message); ruleMessage = new modsecurity::RuleMessage(this, m_log_message);
#ifndef NO_LOGS #ifndef NO_LOGS
std::string eparam = MacroExpansion::expand(this->op->param, trasn); std::string eparam = MacroExpansion::expand(this->op->m_param, trasn);
if (this->op->param != eparam) { if (this->op->m_param != eparam) {
eparam = "\"" + eparam + "\" Was: \"" + this->op->param + "\""; eparam = "\"" + eparam + "\" Was: \"" + this->op->m_param + "\"";
} else { } else {
eparam = "\"" + eparam + "\""; eparam = "\"" + eparam + "\"";
} }
trasn->debug(4, "(Rule: " + std::to_string(rule_id) \ trasn->debug(4, "(Rule: " + std::to_string(rule_id) \
+ ") Executing operator \"" + this->op->op \ + ") Executing operator \"" + this->op->m_op \
+ "\" with param " \ + "\" with param " \
+ eparam \ + eparam \
+ " against " \ + " against " \
@ -384,7 +384,7 @@ bool Rule::evaluate(Transaction *trasn) {
toHexIfNeeded(value)) + "\" (Variable: " + v->m_key + ")"); toHexIfNeeded(value)) + "\" (Variable: " + v->m_key + ")");
#endif #endif
ret = this->op->evaluate(trasn, value); ret = this->op->evaluateInternal(trasn, value);
#ifndef NO_LOGS #ifndef NO_LOGS
clock_t end = clock(); clock_t end = clock();
@ -403,8 +403,8 @@ bool Rule::evaluate(Transaction *trasn) {
if (this->op->m_match_message.empty() == true) { if (this->op->m_match_message.empty() == true) {
ruleMessage->m_match = "Matched \"Operator `" + ruleMessage->m_match = "Matched \"Operator `" +
this->op->op + "' with parameter `" + this->op->m_op + "' with parameter `" +
limitTo(200, this->op->param) + limitTo(200, this->op->m_param) +
"' against variable `" + v->m_key + "' (Value: `" + "' against variable `" + v->m_key + "' (Value: `" +
limitTo(100, toHexIfNeeded(value)) + "' ) \" at " + limitTo(100, toHexIfNeeded(value)) + "' ) \" at " +
v->m_key; v->m_key;

View File

@ -84,7 +84,7 @@ int main(int argc, char **argv) {
continue; continue;
} }
if (z->op != NULL) { if (z->op != NULL) {
std::string op = z->op->op; std::string op = z->op->m_op;
if (operators.count(op) > 0) { if (operators.count(op) > 0) {
operators[op] = 1 + operators[op]; operators[op] = 1 + operators[op];
} else { } else {