Refactoring on the variables resoluvtion method

This commit is contained in:
Felipe Zimmerle 2015-07-14 19:15:54 -03:00
parent 8c408ebcd7
commit 33dff0f1bf
8 changed files with 100 additions and 77 deletions

View File

@ -24,6 +24,8 @@
#include <map>
#include <fstream>
#include <vector>
#include <utility>
#include <chrono>
#endif
#include <stdlib.h>
@ -136,7 +138,8 @@ class Assay {
const char *getResponseBody();
int getResponseBodyLenth();
std::list<std::string> resolve_variable(std::string var);
std::list<std::pair<std::string, std::string>>
resolve_variable(std::string var);
std::string* resolve_variable_first(std::string);
void store_variable(std::string, const std::string &value);
@ -158,6 +161,7 @@ class Assay {
std::string id;
time_t timeStamp;
std::chrono::system_clock::time_point start;
private:
std::ofstream myfile;

View File

@ -1064,13 +1064,32 @@ void Assay::store_variable(std::string key, const std::string &value) {
}
std::list<std::string> Assay::resolve_variable(std::string var) {
std::list<std::string> l;
std::list<std::pair<std::string, std::string>>
Assay::resolve_variable(std::string var) {
std::list<std::pair<std::string, std::string>> l;
std::pair<std::string, std::string> pair;
auto range = m_variables_strings.equal_range(var);
for (auto it = range.first; it != range.second; ++it) {
std::cout << it->first << ' ' << it->second << '\n';
l.push_back(it->second);
pair = std::make_pair(std::string(var), std::string(it->second));
l.push_back(pair);
}
if (l.size() == 0) {
for (auto& x : m_variables_strings) {
if ((x.first.substr(0, var.size() + 1).compare(var + ":") != 0)
&& (x.first != var)) {
continue;
}
std::list<std::pair<std::string, std::string>> t;
t = resolve_variable(x.first);
for (std::pair<std::string, std::string> z : t) {
pair = std::make_pair(std::string(z.first),
std::string(z.second));
l.push_back(pair);
}
}
}
return l;

View File

@ -82,12 +82,13 @@ using ModSecurity::Rule;
%token <std::string> OPERATOR
%token <std::string> ACTION
%token <std::string> VARIABLE
%token <std::string> RUN_TIME_VAR_DUR
%token <std::string> TRANSFORMATION
%token <double> CONFIG_VALUE_NUMBER
%type <std::vector<Action *> *> actions
%type <std::vector<Variable> *> variables
%type <std::vector<Variable *> *> variables
%printer { yyoutput << $$; } <*>;
%%
@ -232,14 +233,26 @@ expression:
variables:
variables PIPE VARIABLE
{
std::vector<Variable> *v = $1;
v->push_back(Variable($3));
std::vector<Variable *> *v = $1;
v->push_back(new Variable($3));
$$ = $1;
}
| VARIABLE
{
std::vector<Variable> *variables = new std::vector<Variable>;
variables->push_back(Variable($1));
std::vector<Variable *> *variables = new std::vector<Variable *>;
variables->push_back(new Variable($1));
$$ = variables;
}
| variables PIPE RUN_TIME_VAR_DUR
{
std::vector<Variable *> *v = $1;
v->push_back(new Variable($3));
$$ = $1;
}
| RUN_TIME_VAR_DUR
{
std::vector<Variable *> *variables = new std::vector<Variable *>;
variables->push_back(new Variable($1));
$$ = variables;
}

View File

@ -56,7 +56,8 @@ OPERATORNOARG (?i:@detectSQLi|@detectXSS|@geoLookup|@validateUrlEncoding|@valida
TRANSFORMATION t:(lowercase|urlDecodeUni|urlDecode|none|compressWhitespace|removeWhitespace|replaceNulls|removeNulls|htmlEntityDecode|jsDecode|cssDecode|trim)
VARIABLE (?i:AUTH_TYPE|ARGS_NAMES|ARGS|QUERY_STRING|REMOTE_ADDR|REQUEST_BASENAME|REQUEST_BODY|REQUEST_COOKIES_NAMES|REQUEST_COOKIES|REQUEST_FILENAME|REQUEST_HEADERS_NAMES|REQUEST_HEADERS|REQUEST_METHOD|REQUEST_PROTOCOL|REQUEST_URI|RESPONSE_BODY|RESPONSE_CONTENT_LENGTH|RESPONSE_CONTENT_TYPE|RESPONSE_HEADERS_NAMES|RESPONSE_HEADERS|RESPONSE_PROTOCOL|RESPONSE_STATUS|TX)
VARIABLE (?i:AUTH_TYPE|ARGS_NAMES|ARGS|QUERY_STRING|REMOTE_ADDR|REQUEST_BASENAME|REQUEST_BODY|REQUEST_COOKIES_NAMES|REQUEST_COOKIES|REQUEST_FILENAME|REQUEST_HEADERS_NAMES|REQUEST_HEADERS|REQUEST_METHOD|REQUEST_PROTOCOL|REQUEST_URI|RESPONSE_BODY|RESPONSE_CONTENT_LENGTH|RESPONSE_CONTENT_TYPE|RESPONSE_HEADERS_NAMES|RESPONSE_HEADERS|RESPONSE_PROTOCOL|RESPONSE_STATUS|TX)
RUN_TIME_VAR_DUR (?i:DURATION)
VARIABLENOCOLON (?i:REQBODY_ERROR|MULTIPART_STRICT_ERROR|MULTIPART_UNMATCHED_BOUNDARY|REMOTE_ADDR|REQUEST_LINE)
@ -121,6 +122,7 @@ FREE_TEXT [^\"]+
[,] { return yy::seclang_parser::make_COMMA(loc); }
[|] { return yy::seclang_parser::make_PIPE(loc); }
{VARIABLE}:?{DICT_ELEMENT}? { return yy::seclang_parser::make_VARIABLE(yytext, loc); }
{RUN_TIME_VAR_DUR} { return yy::seclang_parser::make_RUN_TIME_VAR_DUR(yytext, loc); }
{VARIABLENOCOLON} { return yy::seclang_parser::make_VARIABLE(yytext, loc); }
[ \t]+ { return yy::seclang_parser::make_SPACE(loc); }
\n { return yy::seclang_parser::make_NEW_LINE(loc); }

View File

@ -21,6 +21,7 @@
#include <string>
#include <cstring>
#include <list>
#include <utility>
#include "operators/operator.h"
#include "actions/action.h"
@ -33,7 +34,7 @@ using operators::Operator;
using actions::Action;
Rule::Rule(Operator *_op,
std::vector<Variable> *_variables,
std::vector<Variable *> *_variables,
std::vector<Action *> *_actions)
: variables(_variables),
op(_op),
@ -63,78 +64,59 @@ Rule::Rule(Operator *_op,
}
bool Rule::evaluate(Assay *assay) {
std::vector<Variable> *variables = this->variables;
bool ret = false;
std::vector<Variable *> *variables = this->variables;
assay->debug(4, "Executing operator \"" + this->op->op \
+ "\" with param \"" + this->op->param + "\" against " \
+ Variable::to_s(variables) + ".");
clock_t begin = clock();
for (int i = 0; i < variables->size(); i++) {
Variable variable = variables->at(i);
int transformations = 0;
Variable *variable = variables->at(i);
if (std::strchr(variable.name.c_str(), ':') == NULL) {
for (auto& x : assay->m_variables_strings) {
if ((x.first.substr(0, variable.name.size() + 1).compare( \
variable.name + ":") != 0) && (x.first != variable.name)) {
continue;
}
std::list<std::pair<std::string, std::string>> e =
variable->evaluate(assay);
int transformations = 0;
std::string value = x.second;
for (auto &v : e) {
std::string value = v.second;
for (Action *a :
this->actions_runtime_pre) {
value = a->evaluate(value, assay);
assay->debug(9, " T (" + \
std::to_string(transformations) + ") " + \
a->name + ": \"" + value +"\"");
transformations++;
}
assay->debug(9, "Target value: \"" + value + "\" (Variable: " + \
v.first + ")");
ret = this->op->evaluate(assay, value);
clock_t end = clock();
double elapsed_secs = static_cast<double>(end - begin) \
/ CLOCKS_PER_SEC;
assay->debug(4, "Operator completed in " + \
std::to_string(elapsed_secs) + " seconds");
if (ret) {
assay->debug(4, "Rule returned 1.");
for (Action *a :
this->actions_runtime_pre) {
value = a->evaluate(value, assay);
assay->debug(9, " T (" + \
std::to_string(transformations) + ") " + \
a->name + ": \"" + value +"\"");
transformations++;
}
assay->debug(9, "Target value: \"" + value + "\"");
clock_t begin = clock();
bool ret = this->op->evaluate(assay, value);
clock_t end = clock();
double elapsed_secs = static_cast<double>(end - begin) \
/ CLOCKS_PER_SEC;
assay->debug(4, "Operator completed in " + \
std::to_string(elapsed_secs) + " seconds");
if (ret) {
assay->debug(4, "Rule returned 1.");
for (Action *a :
this->actions_runtime_pos) {
assay->debug(4, "Running action: " + a->action);
a->evaluate(assay);
}
return ret;
} else {
assay->debug(4, "Rule returned 0.");
this->actions_runtime_pos) {
assay->debug(4, "Running action: " + a->action);
a->evaluate(assay);
}
} else {
assay->debug(4, "Rule returned 0.");
}
} else {
bool ret = false;
try {
std::list<std::string> e = assay->resolve_variable(
variable.name);
for (std::string value : e) {
ret = this->op->evaluate(assay,
value);
}
} catch (...) {
}
return ret;
}
return false;
}
return ret;
}
} // namespace ModSecurity

View File

@ -31,7 +31,7 @@ namespace ModSecurity {
class Rule {
public:
Rule(operators::Operator *_op,
std::vector<Variable> *_variables,
std::vector<Variable *> *_variables,
std::vector<actions::Action *> *_actions);
bool evaluate(Assay *assay);
@ -41,7 +41,7 @@ class Rule {
std::vector<actions::Action *> actions_runtime_pre;
std::vector<actions::Action *> actions_runtime_pos;
std::vector<Variable> *variables;
std::vector<Variable *> *variables;
int phase;
double rule_id;
};

View File

@ -24,15 +24,16 @@
namespace ModSecurity {
std::list<std::string> Variable::evaluate(Assay *assay) {
std::list<std::pair<std::string, std::string>>
Variable::evaluate(Assay *assay) {
return assay->resolve_variable(this->name);
}
std::string Variable::to_s(
std::vector<Variable> *variables) {
std::vector<Variable *> *variables) {
std::string ret;
for (int i = 0; i < variables->size() ; i++) {
std::string name = variables->at(i).name;
std::string name = variables->at(i)->name;
if (i == 0) {
ret = ret + name;

View File

@ -16,6 +16,7 @@
#include <vector>
#include <string>
#include <list>
#include <utility>
#ifndef SRC_VARIABLE_H_
#define SRC_VARIABLE_H_
@ -29,8 +30,9 @@ class Variable {
explicit Variable(std::string _name)
: name(_name) { }
static std::string to_s(std::vector<Variable> *variables);
std::list<std::string> evaluate(Assay *assay);
static std::string to_s(std::vector<Variable *> *variables);
virtual std::list<std::pair<std::string, std::string>>
evaluate(Assay *assay);
std::string name;
};