mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-14 13:56:01 +03:00
Refactoring on the variables resoluvtion method
This commit is contained in:
parent
8c408ebcd7
commit
33dff0f1bf
@ -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;
|
||||
|
27
src/assay.cc
27
src/assay.cc
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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); }
|
||||
|
100
src/rule.cc
100
src/rule.cc
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user