Skip to content

Commit

Permalink
Adds support to the validateByteRange operator
Browse files Browse the repository at this point in the history
  • Loading branch information
Felipe Zimmerle committed Jul 28, 2015
1 parent c2d3382 commit a05fa82
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 12 deletions.
106 changes: 96 additions & 10 deletions src/operators/validate_byte_range.cc
Expand Up @@ -22,21 +22,107 @@
namespace ModSecurity {
namespace operators {

bool ValidateByteRange::evaluate(Assay *assay) {
/**
* @todo Implement the operator ValidateByteRange.
* Reference: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#validateByteRange
*/
bool ValidateByteRange::getRange(const std::string &rangeRepresentation,
const char **error) {
size_t pos = param.find_first_of("-");
int start;
int end;

if (pos == std::string::npos) {
try {
start = std::stoi(rangeRepresentation);
} catch(...) {
*error = ("Not able to convert '" + rangeRepresentation + "' into a number").c_str();
return false;
}
table[start >> 3] = (table[start >> 3] | (1 << (start & 0x7)));
return true;
}

try {
start = std::stoi(std::string(rangeRepresentation, 0, pos));
} catch (...) {
*error = ("Not able to convert '" + std::string(rangeRepresentation, 0, pos) + "' into a number").c_str();
return false;
}

try {
end = std::stoi(std::string(rangeRepresentation, pos + 1,
rangeRepresentation.length() - (pos + 1)));
} catch (...) {
*error = ("Not able to convert '" + std::string(rangeRepresentation, pos + 1,
rangeRepresentation.length() - (pos + 1)) + "' into a number").c_str();
return false;
}

if ((start < 0) || (start > 255)) {
*error = ("Invalid range start value: " + std::to_string(start)).c_str();
return false;
}
if ((end < 0) || (end > 255)) {
*error = ("Invalid range end value: " + std::to_string(end)).c_str();
return false;
}
if (start > end) {
*error = ("Invalid range: " + std::to_string(start) + "-" +
std::to_string(end)).c_str();
return false;
}

while(start <= end) {
table[start >> 3] = (table[start >> 3] | (1 << (start & 0x7)));
start++;
}

return true;
}


ValidateByteRange::ValidateByteRange(std::string op, std::string param,
bool negation)
: Operator() {
this->op = op;
this->param = param;
bool ValidateByteRange::init(const char **error) {
size_t pos = param.find_first_of(",");

if (pos == std::string::npos) {
getRange(param, error);
}

while (pos != std::string::npos) {
size_t next_pos = param.find_first_of(",", pos + 1);
if (next_pos == std::string::npos) {
getRange(std::string(param, pos + 1, param.length() - (pos + 1)), error);
} else {
getRange(std::string(param, pos + 1, next_pos), error);
}
pos = next_pos;
}
}



bool ValidateByteRange::evaluate(Assay *assay, const std::string &input) {
bool ret = true;

size_t count = 0;
for(int i = 0; i < input.length(); i++) {
int x = input.at(i);
if (!(table[x >> 3] & (1 << (x & 0x7)))) {
//debug(9, "Value " + std::to_string(x) + " in " + input + " ouside range: " + param);
count++;
}
}

ret = (count != 0);
//if (count == 0) return 0;

//debug(9, "Found %d byte(s) in %s outside range: %s.",
//count, var->name, rule->op_param);

if (negation) {
return !ret;
}

return ret;
}


} // namespace operators
} // namespace ModSecurity
13 changes: 11 additions & 2 deletions src/operators/validate_byte_range.h
Expand Up @@ -27,8 +27,17 @@ namespace operators {
class ValidateByteRange : public Operator {
public:
/** @ingroup ModSecurity_Operator */
ValidateByteRange(std::string o, std::string p, bool i);
bool evaluate(Assay *assay);
ValidateByteRange(std::string op, std::string param, bool negation)
: Operator(op, param, negation) { }

~ValidateByteRange() override { }

bool evaluate(Assay *assay, const std::string &input) override;
bool getRange(const std::string &rangeRepresentation, const char **error);
bool init(const char **error) override;
private:
std::vector<std::string> ranges;
char table[32];
};

} // namespace operators
Expand Down

0 comments on commit a05fa82

Please sign in to comment.