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 <map>
#include <fstream> #include <fstream>
#include <vector> #include <vector>
#include <utility>
#include <chrono>
#endif #endif
#include <stdlib.h> #include <stdlib.h>
@ -136,7 +138,8 @@ class Assay {
const char *getResponseBody(); const char *getResponseBody();
int getResponseBodyLenth(); 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); std::string* resolve_variable_first(std::string);
void store_variable(std::string, const std::string &value); void store_variable(std::string, const std::string &value);
@ -158,6 +161,7 @@ class Assay {
std::string id; std::string id;
time_t timeStamp; time_t timeStamp;
std::chrono::system_clock::time_point start;
private: private:
std::ofstream myfile; 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::pair<std::string, std::string>>
std::list<std::string> l; 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); auto range = m_variables_strings.equal_range(var);
for (auto it = range.first; it != range.second; ++it) { for (auto it = range.first; it != range.second; ++it) {
std::cout << it->first << ' ' << it->second << '\n'; pair = std::make_pair(std::string(var), std::string(it->second));
l.push_back(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; return l;

View File

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

View File

@ -57,6 +57,7 @@ OPERATORNOARG (?i:@detectSQLi|@detectXSS|@geoLookup|@validateUrlEncoding|@valida
TRANSFORMATION t:(lowercase|urlDecodeUni|urlDecode|none|compressWhitespace|removeWhitespace|replaceNulls|removeNulls|htmlEntityDecode|jsDecode|cssDecode|trim) 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) 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_COMMA(loc); }
[|] { return yy::seclang_parser::make_PIPE(loc); } [|] { return yy::seclang_parser::make_PIPE(loc); }
{VARIABLE}:?{DICT_ELEMENT}? { return yy::seclang_parser::make_VARIABLE(yytext, 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); } {VARIABLENOCOLON} { return yy::seclang_parser::make_VARIABLE(yytext, loc); }
[ \t]+ { return yy::seclang_parser::make_SPACE(loc); } [ \t]+ { return yy::seclang_parser::make_SPACE(loc); }
\n { return yy::seclang_parser::make_NEW_LINE(loc); } \n { return yy::seclang_parser::make_NEW_LINE(loc); }

View File

@ -21,6 +21,7 @@
#include <string> #include <string>
#include <cstring> #include <cstring>
#include <list> #include <list>
#include <utility>
#include "operators/operator.h" #include "operators/operator.h"
#include "actions/action.h" #include "actions/action.h"
@ -33,7 +34,7 @@ using operators::Operator;
using actions::Action; using actions::Action;
Rule::Rule(Operator *_op, Rule::Rule(Operator *_op,
std::vector<Variable> *_variables, std::vector<Variable *> *_variables,
std::vector<Action *> *_actions) std::vector<Action *> *_actions)
: variables(_variables), : variables(_variables),
op(_op), op(_op),
@ -63,39 +64,37 @@ Rule::Rule(Operator *_op,
} }
bool Rule::evaluate(Assay *assay) { 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 \ assay->debug(4, "Executing operator \"" + this->op->op \
+ "\" with param \"" + this->op->param + "\" against " \ + "\" with param \"" + this->op->param + "\" against " \
+ Variable::to_s(variables) + "."); + Variable::to_s(variables) + ".");
clock_t begin = clock();
for (int i = 0; i < variables->size(); i++) { for (int i = 0; i < variables->size(); i++) {
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;
}
int transformations = 0; int transformations = 0;
std::string value = x.second; Variable *variable = variables->at(i);
std::list<std::pair<std::string, std::string>> e =
variable->evaluate(assay);
for (auto &v : e) {
std::string value = v.second;
for (Action *a : for (Action *a :
this->actions_runtime_pre) { this->actions_runtime_pre) {
value = a->evaluate(value, assay); value = a->evaluate(value, assay);
assay->debug(9, " T (" + \ assay->debug(9, " T (" + \
std::to_string(transformations) + ") " + \ std::to_string(transformations) + ") " + \
a->name + ": \"" + value +"\""); a->name + ": \"" + value +"\"");
transformations++; transformations++;
} }
assay->debug(9, "Target value: \"" + value + "\""); assay->debug(9, "Target value: \"" + value + "\" (Variable: " + \
clock_t begin = clock(); v.first + ")");
bool ret = this->op->evaluate(assay, value); ret = this->op->evaluate(assay, value);
clock_t end = clock(); clock_t end = clock();
double elapsed_secs = static_cast<double>(end - begin) \ double elapsed_secs = static_cast<double>(end - begin) \
@ -112,29 +111,12 @@ bool Rule::evaluate(Assay *assay) {
assay->debug(4, "Running action: " + a->action); assay->debug(4, "Running action: " + a->action);
a->evaluate(assay); a->evaluate(assay);
} }
return ret;
} else { } else {
assay->debug(4, "Rule returned 0."); 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 ret;
}
return false;
}
} }
} // namespace ModSecurity } // namespace ModSecurity

View File

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

View File

@ -24,15 +24,16 @@
namespace ModSecurity { 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); return assay->resolve_variable(this->name);
} }
std::string Variable::to_s( std::string Variable::to_s(
std::vector<Variable> *variables) { std::vector<Variable *> *variables) {
std::string ret; std::string ret;
for (int i = 0; i < variables->size() ; i++) { 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) { if (i == 0) {
ret = ret + name; ret = ret + name;

View File

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