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