Adds support to the @containsWord operator

This commit is contained in:
Felipe Zimmerle 2015-08-10 17:41:44 -03:00
parent 2f81b62d17
commit 64cbb15335
5 changed files with 53 additions and 33 deletions

View File

@ -18,47 +18,57 @@
#include <string>
#include "operators/operator.h"
#include "src/macro_expansion.h"
namespace ModSecurity {
namespace operators {
bool ContainsWord::acceptableChar(const std::string& a, size_t pos) {
if (a.size() - 1 < pos) {
return false;
}
if ((a.at(pos) >= 65 && a.at(pos) <= 90) ||
(a.at(pos) >= 97 && a.at(pos) <= 122)) {
return false;
}
return true;
}
bool ContainsWord::evaluate(Assay *assay,
std::string input) {
/**
* @todo Implement the operator ContainsWord in a performative way.
*/
const std::string& input) {
std::string paramTarget = MacroExpansion::expand(param, assay);
// FIXME: This is odd logic and should be removed in a future version
if (this->param == "") {
return 1;
if (paramTarget.empty()) {
return true;
}
// If our length is too long we will never match
if (this->param.length() > input.length()) {
return 0;
if (input.empty()) {
return false;
}
// If they are exact matches shortcut
if (this->param == input) {
return 1;
if (input == paramTarget) {
return true;
}
// std::regex r("\\b" + this->param + "\\b");
// std::smatch m;
// if (std::regex_search(input, m, r)) {
// this won't find anything because 'spoons' is not
// the word you're searching for
// return 1;
// }
size_t pos = input.find(paramTarget);
while (pos != std::string::npos) {
if (pos == 0 && acceptableChar(input, paramTarget.size())) {
return true;
}
if (pos + paramTarget.size() == input.size() &&
acceptableChar(input, pos - 1)) {
return true;
}
if (acceptableChar(input, pos - 1) &&
acceptableChar(input, pos + paramTarget.size())) {
return true;
}
pos = input.find(paramTarget, pos + 1);
}
return 0;
return false;
}
ContainsWord::ContainsWord(std::string op,
std::string param, bool negation)
: Operator() {
this->op = op;
this->param = param;
}
} // namespace operators
} // namespace ModSecurity

View File

@ -27,8 +27,12 @@ namespace operators {
class ContainsWord : public Operator {
public:
/** @ingroup ModSecurity_Operator */
ContainsWord(std::string o, std::string p, bool i);
bool evaluate(Assay *assay, std::string exp);
ContainsWord(std::string op, std::string param, bool negation)
: Operator(op, param, negation) { }
bool evaluate(Assay *assay, const std::string &str);
bool acceptableChar(const std::string& a, size_t pos);
};
} // namespace operators

View File

@ -59,7 +59,7 @@
#include "operators/begins_with.h"
#define IF_MATCH(a) \
if (op.compare(1, std::strlen(#a), #a) == 0)
if (op.compare(1, op.length() - 2, #a) == 0)
namespace ModSecurity {
namespace operators {
@ -75,6 +75,9 @@ bool Operator::evaluate(Assay *assay) {
if (assay) {
assay->debug(2, "Operator: " + this->op + \
" is not implemented or malfunctioning.");
} else {
std::cerr << "Operator: " + this->op + \
" is not implemented or malfunctioning.";
}
return true;
}
@ -84,6 +87,9 @@ bool Operator::evaluate(Assay *assay, const std::string& a) {
if (assay) {
assay->debug(2, "Operator: " + this->op + \
" is not implemented or malfunctioning.");
} else {
std::cerr << "Operator: " + this->op + \
" is not implemented or malfunctioning.";
}
return true;

@ -1 +1 @@
Subproject commit a65639f93590edc93ee1c78647cf4b8147e2025d
Subproject commit 93eddefff48e295179d6884691ecb24c362735be

View File

@ -93,7 +93,7 @@ UnitTest *UnitTest::from_yajl_node(yajl_val &node) {
u->param = YAJL_GET_STRING(val);
} else if (strcmp(key, "input") == 0) {
u->input = YAJL_GET_STRING(val);
replaceAll(&(u->input), "\\0", '\0');
replaceAll(&(u->input), "\\0", '\u0000');
replaceAll(&(u->input), "\\xe4", '\xe4');
replaceAll(&(u->input), "\\x03", '\x03');
replaceAll(&(u->input), "\\xbf", '\xbf');