Handling key exceptions on the variable itself

This is the first step towords to solve #1697
This commit is contained in:
Felipe Zimmerle 2018-09-20 09:08:08 -03:00
parent 0d53111cb0
commit ee50fea266
No known key found for this signature in database
GPG Key ID: E6DFB08CE8B11277
54 changed files with 2337 additions and 2080 deletions

View File

@ -41,6 +41,9 @@ class Transaction;
namespace Utils {
class Regex;
}
namespace Variables {
class KeyExclusions;
}
struct MyEqual {
@ -82,6 +85,8 @@ class AnchoredSetVariable : public std::unordered_multimap<std::string,
void setCopy(std::string key, std::string value, size_t offset);
void resolve(std::vector<const VariableValue *> *l);
void resolve(std::vector<const VariableValue *> *l,
Variables::KeyExclusions &ke);
void resolve(const std::string &key,
std::vector<const VariableValue *> *l);
@ -89,6 +94,10 @@ class AnchoredSetVariable : public std::unordered_multimap<std::string,
void resolveRegularExpression(Utils::Regex *r,
std::vector<const VariableValue *> *l);
void resolveRegularExpression(Utils::Regex *r,
std::vector<const VariableValue *> *l,
Variables::KeyExclusions &ke);
std::unique_ptr<std::string> resolveFirst(const std::string &key);
Transaction *m_transaction;

View File

@ -37,11 +37,14 @@ typedef struct Variable_t Variables;
#ifdef __cplusplus
namespace modsecurity {
namespace Variables {
class KeyExclusions;
}
namespace collection {
class Collection {
public:
Collection(std::string a) : m_name(a) { }
explicit Collection(std::string a) : m_name(a) { }
virtual ~Collection() { }
virtual void store(std::string key, std::string value) = 0;
@ -59,9 +62,11 @@ class Collection {
virtual void resolveSingleMatch(const std::string& var,
std::vector<const VariableValue *> *l) = 0;
virtual void resolveMultiMatches(const std::string& var,
std::vector<const VariableValue *> *l) = 0;
std::vector<const VariableValue *> *l,
Variables::KeyExclusions &ke) = 0;
virtual void resolveRegularExpression(const std::string& var,
std::vector<const VariableValue *> *l) = 0;
std::vector<const VariableValue *> *l,
Variables::KeyExclusions &ke) = 0;
/* store */
@ -157,33 +162,36 @@ class Collection {
/* resolveMultiMatches */
virtual void resolveMultiMatches(const std::string& var,
std::string compartment, std::vector<const VariableValue *> *l) {
std::string compartment, std::vector<const VariableValue *> *l,
Variables::KeyExclusions &ke) {
std::string nkey = compartment + "::" + var;
resolveMultiMatches(nkey, l);
resolveMultiMatches(nkey, l, ke);
}
virtual void resolveMultiMatches(const std::string& var,
std::string compartment, std::string compartment2,
std::vector<const VariableValue *> *l) {
std::vector<const VariableValue *> *l,
Variables::KeyExclusions &ke) {
std::string nkey = compartment + "::" + compartment2 + "::" + var;
resolveMultiMatches(nkey, l);
resolveMultiMatches(nkey, l, ke);
}
/* resolveRegularExpression */
virtual void resolveRegularExpression(const std::string& var,
std::string compartment, std::vector<const VariableValue *> *l) {
std::string compartment, std::vector<const VariableValue *> *l,
Variables::KeyExclusions &ke) {
std::string nkey = compartment + "::" + var;
resolveRegularExpression(nkey, l);
resolveRegularExpression(nkey, l, ke);
}
virtual void resolveRegularExpression(const std::string& var,
std::string compartment, std::string compartment2,
std::vector<const VariableValue *> *l) {
std::vector<const VariableValue *> *l, Variables::KeyExclusions &ke) {
std::string nkey = compartment + "::" + compartment2 + "::" + var;
resolveRegularExpression(nkey, l);
resolveRegularExpression(nkey, l, ke);
}
std::string m_name;

View File

@ -371,8 +371,9 @@ class RulesProperties {
from->m_responseBodyTypeToBeInspected.m_value.clear();
} else {
for (std::set<std::string>::iterator
it = from->m_responseBodyTypeToBeInspected.m_value.begin();
it != from->m_responseBodyTypeToBeInspected.m_value.end(); ++it) {
it = from->m_responseBodyTypeToBeInspected.m_value.begin();
it != from->m_responseBodyTypeToBeInspected.m_value.end();
++it) {
to->m_responseBodyTypeToBeInspected.m_value.insert(*it);
}
}
@ -433,7 +434,7 @@ class RulesProperties {
for (int i = 0; i < modsecurity::Phases::NUMBER_OF_PHASES; i++) {
std::vector<modsecurity::Rule *> *rules_to = to+i;
std::vector<modsecurity::Rule *> *rules_from = from+i;
// TODO: std::vector could be replaced with something more efficient.
// FIXME: std::vector could be replaced with something more efficient.
std::vector<int64_t> v;
v.reserve(rules_to->size());
for (size_t z = 0; z < rules_to->size(); z++) {
@ -443,11 +444,11 @@ class RulesProperties {
}
v.push_back(rule_ckc->m_ruleId);
}
std::sort (v.begin(), v.end());
std::sort(v.begin(), v.end());
for (size_t j = 0; j < rules_from->size(); j++) {
Rule *rule = rules_from->at(j);
if (std::binary_search (v.begin(), v.end(), rule->m_ruleId)) {
if (std::binary_search(v.begin(), v.end(), rule->m_ruleId)) {
if (err != NULL) {
*err << "Rule id: " \
<< std::to_string(rule->m_ruleId) \

View File

@ -40,8 +40,8 @@ typedef struct Transaction_t Transaction;
typedef struct Rules_t Rules;
#endif
#include "anchored_set_variable.h"
#include "anchored_variable.h"
#include "modsecurity/anchored_set_variable.h"
#include "modsecurity/anchored_variable.h"
#include "modsecurity/intervention.h"
#include "modsecurity/collection/collections.h"
#include "modsecurity/variable_value.h"

View File

@ -24,8 +24,8 @@
#include "modsecurity/variable_origin.h"
#ifndef HEADERS_MODSECURITY_VARIABLE_H_
#define HEADERS_MODSECURITY_VARIABLE_H_
#ifndef HEADERS_MODSECURITY_VARIABLE_VALUE_H_
#define HEADERS_MODSECURITY_VARIABLE_VALUE_H_
#ifndef __cplusplus
typedef struct Variable_t VariableValue;
@ -37,42 +37,44 @@ namespace modsecurity {
class Collection;
class VariableValue {
public:
explicit VariableValue(const std::string *key) :
m_key(""),
explicit VariableValue(const std::string *key)
: m_key(""),
m_value("") {
m_key.assign(*key);
m_keyWithCollection = std::make_shared<std::string>(*key);
}
VariableValue(const std::string *key, const std::string *value) :
m_key(""),
VariableValue(const std::string *key, const std::string *value)
: m_key(""),
m_value("") {
m_key.assign(*key);
m_value.assign(*value);
m_keyWithCollection = std::make_shared<std::string>(*key);
}
VariableValue() :
m_key(""),
VariableValue()
: m_key(""),
m_value("") {
m_keyWithCollection = std::make_shared<std::string>(m_key);
}
VariableValue(const std::string *a, const std::string *b, const std::string *c) :
m_key(*a + ":" + *b),
VariableValue(const std::string *a, const std::string *b,
const std::string *c)
: m_key(*a + ":" + *b),
m_value(*c) {
m_keyWithCollection = std::make_shared<std::string>(*a + ":" + *b);
}
VariableValue(std::shared_ptr<std::string> fullName) :
m_key(""),
explicit VariableValue(std::shared_ptr<std::string> fullName)
: m_key(""),
m_value("") {
m_keyWithCollection = fullName;
m_key.assign(*fullName.get());
}
VariableValue(std::shared_ptr<std::string> fullName, const std::string *value) :
m_key(""),
VariableValue(std::shared_ptr<std::string> fullName,
const std::string *value)
: m_key(""),
m_value("") {
m_value.assign(*value);
m_keyWithCollection = fullName;
@ -106,4 +108,4 @@ class VariableValue {
} // namespace modsecurity
#endif
#endif // HEADERS_MODSECURITY_VARIABLE_H_
#endif // HEADERS_MODSECURITY_VARIABLE_VALUE_H_

View File

@ -52,12 +52,18 @@ bool SetVar::evaluate(Rule *rule, Transaction *t) {
std::vector<const VariableValue *> l;
auto *v = m_variable.get();
Variables::Tx_DynamicElement *tx = dynamic_cast<Variables::Tx_DynamicElement *> (v);
Variables::Session_DynamicElement *session = dynamic_cast<Variables::Session_DynamicElement *> (v);
Variables::Ip_DynamicElement *ip = dynamic_cast<Variables::Ip_DynamicElement *> (v);
Variables::Resource_DynamicElement *resource = dynamic_cast<Variables::Resource_DynamicElement *> (v);
Variables::Global_DynamicElement *global = dynamic_cast<Variables::Global_DynamicElement *> (v);
Variables::User_DynamicElement *user = dynamic_cast<Variables::User_DynamicElement *> (v);
Variables::Tx_DynamicElement *tx = dynamic_cast<
Variables::Tx_DynamicElement *> (v);
Variables::Session_DynamicElement *session = dynamic_cast<
Variables::Session_DynamicElement *> (v);
Variables::Ip_DynamicElement *ip = dynamic_cast<
Variables::Ip_DynamicElement *> (v);
Variables::Resource_DynamicElement *resource = dynamic_cast<
Variables::Resource_DynamicElement *> (v);
Variables::Global_DynamicElement *global = dynamic_cast<
Variables::Global_DynamicElement *> (v);
Variables::User_DynamicElement *user = dynamic_cast<
Variables::User_DynamicElement *> (v);
if (tx) {
m_variableNameExpanded = tx->m_string->evaluate(t);
} else if (session) {

View File

@ -13,7 +13,9 @@
*
*/
#include <memory>
#include <string>
#include <utility>
#include "modsecurity/actions/action.h"
#include "src/run_time_string.h"

View File

@ -23,6 +23,7 @@
#include "modsecurity/modsecurity.h"
#include "modsecurity/transaction.h"
#include "src/utils/regex.h"
#include "src/variables/variable.h"
namespace modsecurity {
@ -52,7 +53,8 @@ void AnchoredSetVariable::set(const std::string &key,
const std::string &value, size_t offset, size_t len) {
std::unique_ptr<VariableOrigin> origin(new VariableOrigin());
std::string *v = new std::string(value);
VariableValue *var = new VariableValue(std::make_shared<std::string>(m_name + ":" + key), v);
VariableValue *var = new VariableValue(std::make_shared<std::string>(
m_name + ":" + key), v);
delete v;
origin->m_offset = offset;
@ -67,7 +69,8 @@ void AnchoredSetVariable::set(const std::string &key,
const std::string &value, size_t offset) {
std::unique_ptr<VariableOrigin> origin(new VariableOrigin());
std::string *v = new std::string(value);
VariableValue *var = new VariableValue(std::make_shared<std::string>(m_name + ":" + key), v);
VariableValue *var = new VariableValue(std::make_shared<std::string>(
m_name + ":" + key), v);
delete v;
origin->m_offset = offset;
@ -86,6 +89,20 @@ void AnchoredSetVariable::resolve(
}
void AnchoredSetVariable::resolve(
std::vector<const VariableValue *> *l,
Variables::KeyExclusions &ke) {
for (const auto& x : *this) {
if (!ke.toOmit(x.first)) {
l->insert(l->begin(), new VariableValue(x.second));
} else {
m_transaction->debug(7, "Excluding key: " + x.first
+ " from target value.");
}
}
}
void AnchoredSetVariable::resolve(const std::string &key,
std::vector<const VariableValue *> *l) {
auto range = this->equal_range(key);
@ -119,4 +136,22 @@ void AnchoredSetVariable::resolveRegularExpression(Utils::Regex *r,
}
void AnchoredSetVariable::resolveRegularExpression(Utils::Regex *r,
std::vector<const VariableValue *> *l,
Variables::KeyExclusions &ke) {
for (const auto& x : *this) {
int ret = Utils::regex_search(x.first, *r);
if (ret <= 0) {
continue;
}
if (!ke.toOmit(x.first)) {
l->insert(l->begin(), new VariableValue(x.second));
} else {
m_transaction->debug(7, "Excluding key: " + x.first
+ " from target value.");
}
}
}
} // namespace modsecurity

View File

@ -96,25 +96,33 @@ void InMemoryPerProcess::resolveSingleMatch(const std::string& var,
void InMemoryPerProcess::resolveMultiMatches(const std::string& var,
std::vector<const VariableValue *> *l) {
std::vector<const VariableValue *> *l, Variables::KeyExclusions &ke) {
size_t keySize = var.size();
l->reserve(15);
if (keySize == 0) {
for (auto &i : *this) {
l->insert(l->begin(), new VariableValue(&m_name, &i.first, &i.second));
if (ke.toOmit(i.first)) {
continue;
}
l->insert(l->begin(), new VariableValue(&m_name, &i.first,
&i.second));
}
} else {
auto range = this->equal_range(var);
for (auto it = range.first; it != range.second; ++it) {
l->insert(l->begin(), new VariableValue(&m_name, &var, &it->second));
if (ke.toOmit(var)) {
continue;
}
l->insert(l->begin(), new VariableValue(&m_name, &var,
&it->second));
}
}
}
void InMemoryPerProcess::resolveRegularExpression(const std::string& var,
std::vector<const VariableValue *> *l) {
std::vector<const VariableValue *> *l, Variables::KeyExclusions &ke) {
//if (var.find(":") == std::string::npos) {
// return;
@ -144,7 +152,9 @@ void InMemoryPerProcess::resolveRegularExpression(const std::string& var,
if (ret <= 0) {
continue;
}
if (ke.toOmit(x.first)) {
continue;
}
l->insert(l->begin(), new VariableValue(&m_name, &x.first, &x.second));
}
}

View File

@ -27,6 +27,7 @@
#include "modsecurity/variable_value.h"
#include "modsecurity/collection/collection.h"
#include "src/variables/variable.h"
#ifndef SRC_COLLECTION_BACKEND_IN_MEMORY_PER_PROCESS_H_
#define SRC_COLLECTION_BACKEND_IN_MEMORY_PER_PROCESS_H_
@ -71,7 +72,7 @@ class InMemoryPerProcess :
/*std::hash<std::string>*/MyHash, MyEqual>,
public Collection {
public:
InMemoryPerProcess(std::string name);
explicit InMemoryPerProcess(std::string name);
~InMemoryPerProcess();
void store(std::string key, std::string value) override;
@ -88,9 +89,11 @@ class InMemoryPerProcess :
void resolveSingleMatch(const std::string& var,
std::vector<const VariableValue *> *l) override;
void resolveMultiMatches(const std::string& var,
std::vector<const VariableValue *> *l) override;
std::vector<const VariableValue *> *l,
Variables::KeyExclusions &ke) override;
void resolveRegularExpression(const std::string& var,
std::vector<const VariableValue *> *l) override;
std::vector<const VariableValue *> *l,
Variables::KeyExclusions &ke) override;
private:
pthread_mutex_t m_lock;

View File

@ -24,6 +24,7 @@
#include "modsecurity/variable_value.h"
#include "src/utils/regex.h"
#include "src/variables/variable.h"
#undef LMDB_STDOUT_COUT
@ -465,7 +466,8 @@ end_txn:
void LMDB::resolveMultiMatches(const std::string& var,
std::vector<const VariableValue *> *l) {
std::vector<const VariableValue *> *l,
Variables::KeyExclusions &ke) {
MDB_val key, data;
MDB_txn *txn = NULL;
MDB_dbi dbi;
@ -495,24 +497,22 @@ void LMDB::resolveMultiMatches(const std::string& var,
if (keySize == 0) {
while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
l->insert(l->begin(), new VariableValue(
&m_name,
&m_name,
new std::string(reinterpret_cast<char *>(key.mv_data),
key.mv_size),
new std::string(reinterpret_cast<char *>(data.mv_data),
data.mv_size))
);
data.mv_size)));
}
} else {
while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
char *a = reinterpret_cast<char *>(key.mv_data);
if (strncmp(var.c_str(), a, keySize) == 0) {
l->insert(l->begin(), new VariableValue(
&m_name,
&m_name,
new std::string(reinterpret_cast<char *>(key.mv_data),
key.mv_size),
new std::string(reinterpret_cast<char *>(data.mv_data),
data.mv_size))
);
data.mv_size)));
}
}
}
@ -528,7 +528,8 @@ end_txn:
void LMDB::resolveRegularExpression(const std::string& var,
std::vector<const VariableValue *> *l) {
std::vector<const VariableValue *> *l,
Variables::KeyExclusions &ke) {
MDB_val key, data;
MDB_txn *txn = NULL;
MDB_dbi dbi;
@ -563,6 +564,11 @@ void LMDB::resolveRegularExpression(const std::string& var,
if (ret <= 0) {
continue;
}
if (ke.toOmit(std::string(reinterpret_cast<char *>(key.mv_data),
key.mv_size))) {
continue;
}
VariableValue *v = new VariableValue(
new std::string(reinterpret_cast<char *>(key.mv_data),
key.mv_size),

View File

@ -36,6 +36,7 @@
#include "modsecurity/variable_value.h"
#include "modsecurity/collection/collection.h"
#include "src/variables/variable.h"
#ifndef SRC_COLLECTION_BACKEND_LMDB_H_
#define SRC_COLLECTION_BACKEND_LMDB_H_
@ -50,7 +51,7 @@ namespace backend {
class LMDB :
public Collection {
public:
LMDB(std::string name);
explicit LMDB(std::string name);
~LMDB();
void store(std::string key, std::string value) override;
@ -67,9 +68,11 @@ class LMDB :
void resolveSingleMatch(const std::string& var,
std::vector<const VariableValue *> *l) override;
void resolveMultiMatches(const std::string& var,
std::vector<const VariableValue *> *l) override;
std::vector<const VariableValue *> *l,
Variables::KeyExclusions &ke) override;
void resolveRegularExpression(const std::string& var,
std::vector<const VariableValue *> *l) override;
std::vector<const VariableValue *> *l,
Variables::KeyExclusions &ke) override;
private:
void string2val(const std::string& str, MDB_val *val);

View File

@ -71,8 +71,10 @@ ModSecurity::ModSecurity()
#else
m_global_collection(new collection::backend::InMemoryPerProcess("GLOBAL")),
m_ip_collection(new collection::backend::InMemoryPerProcess("IP")),
m_resource_collection(new collection::backend::InMemoryPerProcess("RESOURCE")),
m_session_collection(new collection::backend::InMemoryPerProcess("SESSION")),
m_resource_collection(
new collection::backend::InMemoryPerProcess("RESOURCE")),
m_session_collection(
new collection::backend::InMemoryPerProcess("SESSION")),
m_user_collection(new collection::backend::InMemoryPerProcess("USER")),
#endif
m_logCb(NULL) {

View File

@ -16,10 +16,10 @@
#include "src/operators/ip_match_from_file.h"
#include "src/utils/system.h"
#include <string.h>
#include <string>
#include <string.h>
#include "src/operators/operator.h"
namespace modsecurity {

File diff suppressed because it is too large Load Diff

View File

@ -836,6 +836,7 @@ namespace yy {
char dummy5[sizeof(std::unique_ptr<actions::Action>)];
// variables
// variables_pre_process
// variables_may_be_quoted
char dummy6[sizeof(std::unique_ptr<std::vector<std::unique_ptr<Variable> > > )];
@ -2874,9 +2875,9 @@ namespace yy {
enum
{
yyeof_ = 0,
yylast_ = 3319, ///< Last index in yytable_.
yynnts_ = 15, ///< Number of nonterminal symbols.
yyfinal_ = 335, ///< Termination state number.
yylast_ = 3320, ///< Last index in yytable_.
yynnts_ = 16, ///< Number of nonterminal symbols.
yyfinal_ = 336, ///< Termination state number.
yyterror_ = 1,
yyerrcode_ = 256,
yyntokens_ = 339 ///< Number of tokens.
@ -3191,21 +3192,22 @@ namespace yy {
value.copy< std::unique_ptr<Operator> > (other.value);
break;
case 353: // run_time_string
case 354: // run_time_string
value.copy< std::unique_ptr<RunTimeString> > (other.value);
break;
case 350: // var
case 351: // var
value.copy< std::unique_ptr<Variable> > (other.value);
break;
case 351: // act
case 352: // setvar_action
case 352: // act
case 353: // setvar_action
value.copy< std::unique_ptr<actions::Action> > (other.value);
break;
case 348: // variables
case 349: // variables_may_be_quoted
case 349: // variables_pre_process
case 350: // variables_may_be_quoted
value.copy< std::unique_ptr<std::vector<std::unique_ptr<Variable> > > > (other.value);
break;
@ -3432,21 +3434,22 @@ namespace yy {
value.copy< std::unique_ptr<Operator> > (v);
break;
case 353: // run_time_string
case 354: // run_time_string
value.copy< std::unique_ptr<RunTimeString> > (v);
break;
case 350: // var
case 351: // var
value.copy< std::unique_ptr<Variable> > (v);
break;
case 351: // act
case 352: // setvar_action
case 352: // act
case 353: // setvar_action
value.copy< std::unique_ptr<actions::Action> > (v);
break;
case 348: // variables
case 349: // variables_may_be_quoted
case 349: // variables_pre_process
case 350: // variables_may_be_quoted
value.copy< std::unique_ptr<std::vector<std::unique_ptr<Variable> > > > (v);
break;
@ -3746,21 +3749,22 @@ namespace yy {
value.template destroy< std::unique_ptr<Operator> > ();
break;
case 353: // run_time_string
case 354: // run_time_string
value.template destroy< std::unique_ptr<RunTimeString> > ();
break;
case 350: // var
case 351: // var
value.template destroy< std::unique_ptr<Variable> > ();
break;
case 351: // act
case 352: // setvar_action
case 352: // act
case 353: // setvar_action
value.template destroy< std::unique_ptr<actions::Action> > ();
break;
case 348: // variables
case 349: // variables_may_be_quoted
case 349: // variables_pre_process
case 350: // variables_may_be_quoted
value.template destroy< std::unique_ptr<std::vector<std::unique_ptr<Variable> > > > ();
break;
@ -3993,21 +3997,22 @@ namespace yy {
value.move< std::unique_ptr<Operator> > (s.value);
break;
case 353: // run_time_string
case 354: // run_time_string
value.move< std::unique_ptr<RunTimeString> > (s.value);
break;
case 350: // var
case 351: // var
value.move< std::unique_ptr<Variable> > (s.value);
break;
case 351: // act
case 352: // setvar_action
case 352: // act
case 353: // setvar_action
value.move< std::unique_ptr<actions::Action> > (s.value);
break;
case 348: // variables
case 349: // variables_may_be_quoted
case 349: // variables_pre_process
case 350: // variables_may_be_quoted
value.move< std::unique_ptr<std::vector<std::unique_ptr<Variable> > > > (s.value);
break;
@ -6134,7 +6139,7 @@ namespace yy {
} // yy
#line 6138 "seclang-parser.hh" // lalr1.cc:379
#line 6143 "seclang-parser.hh" // lalr1.cc:379

View File

@ -725,7 +725,7 @@ using modsecurity::operators::Operator;
op
;
%type <std::unique_ptr<std::vector<std::unique_ptr<Variable> > > > variables_pre_process
%type <std::unique_ptr<std::vector<std::unique_ptr<Variable> > > > variables_may_be_quoted
%type <std::unique_ptr<std::vector<std::unique_ptr<Variable> > > > variables
%type <std::unique_ptr<Variable>> var
@ -1443,7 +1443,7 @@ expression:
YYERROR;
}
}
| CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG variables
| CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG variables_pre_process
{
std::string error;
if (driver.m_exceptions.loadUpdateTargetByTag($1, std::move($2), &error) == false) {
@ -1456,7 +1456,7 @@ expression:
YYERROR;
}
}
| CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG variables
| CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG variables_pre_process
{
std::string error;
if (driver.m_exceptions.loadUpdateTargetByMsg($1, std::move($2), &error) == false) {
@ -1469,7 +1469,7 @@ expression:
YYERROR;
}
}
| CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID variables
| CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID variables_pre_process
{
std::string error;
double ruleId;
@ -1723,6 +1723,43 @@ expression:
;
variables:
variables_pre_process
{
std::unique_ptr<std::vector<std::unique_ptr<Variable> > > originalList = std::move($1);
std::unique_ptr<std::vector<std::unique_ptr<Variable>>> newList(new std::vector<std::unique_ptr<Variable>>());
std::unique_ptr<std::vector<std::unique_ptr<Variable>>> newNewList(new std::vector<std::unique_ptr<Variable>>());
std::unique_ptr<std::vector<std::unique_ptr<Variable>>> exclusionVars(new std::vector<std::unique_ptr<Variable>>());
while (!originalList->empty()) {
std::unique_ptr<Variable> var = std::move(originalList->back());
originalList->pop_back();
if (var->m_isExclusion) {
exclusionVars->push_back(std::move(var));
} else {
newList->push_back(std::move(var));
}
}
while (!newList->empty()) {
bool doNotAdd = false;
std::unique_ptr<Variable> var = std::move(newList->back());
newList->pop_back();
for (auto &i : *exclusionVars) {
if (*var == *i) {
doNotAdd = true;
}
if (i->belongsToCollection(var.get())) {
var->addsKeyExclusion(i.get());
}
}
if (!doNotAdd) {
newNewList->push_back(std::move(var));
}
}
$$ = std::move(newNewList);
}
;
variables_pre_process:
variables_may_be_quoted
{
$$ = std::move($1);

View File

@ -422,7 +422,6 @@ std::list<std::pair<std::shared_ptr<std::string>,
std::vector<std::unique_ptr<VariableValue>> Rule::getFinalVars(
Transaction *trans) {
std::list<std::string> exclusions;
std::list<std::string> exclusions_update_by_tag_remove;
std::list<std::string> exclusions_update_by_msg_remove;
std::list<std::string> exclusions_update_by_id_remove;
@ -496,43 +495,17 @@ std::vector<std::unique_ptr<VariableValue>> Rule::getFinalVars(
}
}
for (int i = 0; i < variables.size(); i++) {
Variable *variable = variables.at(i);
if (variable->m_isExclusion) {
std::vector<const VariableValue *> z;
variable->evaluate(trans, this, &z);
for (auto &y : z) {
exclusions.push_back(std::string(y->m_key));
delete y;
}
exclusions.push_back(std::string(variable->m_name));
}
}
for (int i = 0; i < variables.size(); i++) {
Variable *variable = variables.at(i);
std::vector<const VariableValue *> e;
bool ignoreVariable = false;
if (variable->m_isExclusion) {
continue;
}
variable->evaluate(trans, this, &e);
for (const VariableValue *v : e) {
std::string key = v->m_key;
if (std::find_if(exclusions.begin(), exclusions.end(),
[key](std::string m) -> bool { return key == m; })
!= exclusions.end()) {
#ifndef NO_LOGS
trans->debug(9, "Variable: " + key +
" is part of the exclusion list, skipping...");
#endif
delete v;
v = NULL;
continue;
}
if (std::find_if(exclusions_update_by_tag_remove.begin(),
exclusions_update_by_tag_remove.end(),
[key](std::string m) -> bool { return key == m; })
@ -575,6 +548,7 @@ std::vector<std::unique_ptr<VariableValue>> Rule::getFinalVars(
continue;
}
for (auto &i : trans->m_ruleRemoveTargetByTag) {
std::string tag = i.first;
std::string args = i.second;
@ -604,12 +578,15 @@ std::vector<std::unique_ptr<VariableValue>> Rule::getFinalVars(
}
}
}
if (ignoreVariable) {
delete v;
v = NULL;
continue;
}
for (auto &i : trans->m_ruleRemoveTargetById) {
int id = i.first;
std::string args = i.second;
@ -641,6 +618,8 @@ std::vector<std::unique_ptr<VariableValue>> Rule::getFinalVars(
}
}
}
if (ignoreVariable) {
delete v;
v = NULL;

View File

@ -53,7 +53,7 @@ class Args_NoDictElement : public Variable {
void evaluate(Transaction *transaction,
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableArgs.resolve(l);
transaction->m_variableArgs.resolve(l, m_keyExclusion);
}
};
@ -68,7 +68,8 @@ class Args_DictElementRegexp : public Variable {
void evaluate(Transaction *transaction,
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableArgs.resolveRegularExpression(&m_r, l);
transaction->m_variableArgs.resolveRegularExpression(&m_r, l,
m_keyExclusion);
}
Utils::Regex m_r;

View File

@ -53,7 +53,7 @@ class ArgsGet_NoDictElement : public Variable {
void evaluate(Transaction *transaction,
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableArgsGet.resolve(l);
transaction->m_variableArgsGet.resolve(l, m_keyExclusion);
}
};
@ -67,7 +67,8 @@ class ArgsGet_DictElementRegexp : public Variable {
void evaluate(Transaction *transaction,
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableArgsGet.resolveRegularExpression(&m_r, l);
transaction->m_variableArgsGet.resolveRegularExpression(&m_r, l,
m_keyExclusion);
}
Utils::Regex m_r;

View File

@ -53,7 +53,7 @@ class ArgsGetNames_NoDictElement : public Variable {
void evaluate(Transaction *transaction,
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableArgsGetNames.resolve(l);
transaction->m_variableArgsGetNames.resolve(l, m_keyExclusion);
}
};
@ -67,7 +67,7 @@ class ArgsGetNames_DictElementRegexp : public Variable {
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableArgsGetNames.resolveRegularExpression(
&m_r, l);
&m_r, l, m_keyExclusion);
}
Utils::Regex m_r;

View File

@ -53,7 +53,7 @@ class ArgsNames_NoDictElement : public Variable {
void evaluate(Transaction *transaction,
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableArgsNames.resolve(l);
transaction->m_variableArgsNames.resolve(l, m_keyExclusion);
}
};
@ -67,7 +67,7 @@ class ArgsNames_DictElementRegexp : public Variable {
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableArgsNames.resolveRegularExpression(
&m_r, l);
&m_r, l, m_keyExclusion);
}
Utils::Regex m_r;

View File

@ -53,7 +53,7 @@ class ArgsPost_NoDictElement : public Variable {
void evaluate(Transaction *transaction,
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableArgsPost.resolve(l);
transaction->m_variableArgsPost.resolve(l, m_keyExclusion);
}
};
@ -67,7 +67,8 @@ class ArgsPost_DictElementRegexp : public Variable {
void evaluate(Transaction *transaction,
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableArgsPost.resolveRegularExpression(&m_r, l);
transaction->m_variableArgsPost.resolveRegularExpression(&m_r, l,
m_keyExclusion);
}
Utils::Regex m_r;

View File

@ -53,7 +53,7 @@ class ArgsPostNames_NoDictElement : public Variable {
void evaluate(Transaction *transaction,
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableArgsPostNames.resolve(l);
transaction->m_variableArgsPostNames.resolve(l, m_keyExclusion);
}
};
@ -67,7 +67,7 @@ class ArgsPostNames_DictElementRegexp : public Variable {
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableArgsPostNames.resolveRegularExpression(
&m_r, l);
&m_r, l, m_keyExclusion);
}
Utils::Regex m_r;

View File

@ -51,7 +51,10 @@ void Env::evaluate(Transaction *transaction,
if (x.first != m_name && m_name.length() > 0) {
continue;
}
l->push_back(new VariableValue(&m_collectionName, &x.first, &x.second));
if (!m_keyExclusion.toOmit(x.first)) {
l->push_back(new VariableValue(&m_collectionName, &x.first,
&x.second));
}
}
}

View File

@ -38,7 +38,6 @@ class Env : public Variable {
std::vector<const VariableValue *> *l) override;
};
} // namespace Variables
} // namespace modsecurity

View File

@ -54,7 +54,7 @@ class Files_NoDictElement : public Variable {
void evaluate(Transaction *transaction,
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableFiles.resolve(l);
transaction->m_variableFiles.resolve(l, m_keyExclusion);
}
};
@ -69,7 +69,7 @@ class Files_DictElementRegexp : public Variable {
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableFiles.resolveRegularExpression(
&m_r, l);
&m_r, l, m_keyExclusion);
}
Utils::Regex m_r;

View File

@ -54,7 +54,7 @@ class FilesNames_NoDictElement : public Variable {
void evaluate(Transaction *transaction,
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableFilesNames.resolve(l);
transaction->m_variableFilesNames.resolve(l, m_keyExclusion);
}
};
@ -70,7 +70,7 @@ class FilesNames_DictElementRegexp : public Variable {
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableFilesNames.resolveRegularExpression(
&m_r, l);
&m_r, l, m_keyExclusion);
}
Utils::Regex m_r;

View File

@ -54,7 +54,7 @@ class FilesSizes_NoDictElement : public Variable {
void evaluate(Transaction *transaction,
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableFilesSizes.resolve(l);
transaction->m_variableFilesSizes.resolve(l, m_keyExclusion);
}
};
@ -69,7 +69,7 @@ class FilesSizes_DictElementRegexp : public Variable {
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableFilesSizes.resolveRegularExpression(
&m_r, l);
&m_r, l, m_keyExclusion);
}
Utils::Regex m_r;

View File

@ -54,7 +54,7 @@ class FilesTmpContent_NoDictElement : public Variable {
void evaluate(Transaction *transaction,
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableFilesTmpContent.resolve(l);
transaction->m_variableFilesTmpContent.resolve(l, m_keyExclusion);
}
};
@ -69,7 +69,7 @@ class FilesTmpContent_DictElementRegexp : public Variable {
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableFilesTmpContent.resolveRegularExpression(
&m_r, l);
&m_r, l, m_keyExclusion);
}
Utils::Regex m_r;

View File

@ -53,7 +53,7 @@ class FilesTmpNames_NoDictElement : public Variable {
void evaluate(Transaction *transaction,
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableFilesTmpNames.resolve(l);
transaction->m_variableFilesTmpNames.resolve(l, m_keyExclusion);
}
};
@ -68,7 +68,7 @@ class FilesTmpNames_DictElementRegexp : public Variable {
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableFilesTmpNames.resolveRegularExpression(
&m_r, l);
&m_r, l, m_keyExclusion);
}
Utils::Regex m_r;

View File

@ -54,7 +54,7 @@ class Geo_NoDictElement : public Variable {
void evaluate(Transaction *transaction,
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableGeo.resolve(l);
transaction->m_variableGeo.resolve(l, m_keyExclusion);
}
};
@ -69,7 +69,7 @@ class Geo_DictElementRegexp : public Variable {
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableGeo.resolveRegularExpression(
&m_r, l);
&m_r, l, m_keyExclusion);
}
Utils::Regex m_r;

View File

@ -14,10 +14,11 @@
*/
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#ifndef SRC_VARIABLES_GLOBAL_H_
#define SRC_VARIABLES_GLOBAL_H_
@ -42,7 +43,7 @@ class Global_DictElement : public Variable {
std::vector<const VariableValue *> *l) override {
t->m_collections.m_global_collection->resolveMultiMatches(
m_name, t->m_collections.m_global_collection_key,
t->m_rules->m_secWebAppId.m_value, l);
t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);
}
std::string m_dictElement;
@ -59,7 +60,7 @@ class Global_NoDictElement : public Variable {
std::vector<const VariableValue *> *l) override {
t->m_collections.m_global_collection->resolveMultiMatches("",
t->m_collections.m_global_collection_key,
t->m_rules->m_secWebAppId.m_value, l);
t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);
}
};
@ -77,7 +78,7 @@ class Global_DictElementRegexp : public Variable {
t->m_collections.m_global_collection->resolveRegularExpression(
m_dictElement,
t->m_collections.m_global_collection_key,
t->m_rules->m_secWebAppId.m_value, l);
t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);
}
Utils::Regex m_r;
@ -98,8 +99,7 @@ class Global_DynamicElement : public Variable {
t->m_collections.m_global_collection->resolveMultiMatches(
string,
t->m_collections.m_global_collection_key,
t->m_rules->m_secWebAppId.m_value, l);
t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);
}
void del(Transaction *t, std::string k) {

View File

@ -14,10 +14,11 @@
*/
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#ifndef SRC_VARIABLES_IP_H_
#define SRC_VARIABLES_IP_H_
@ -42,7 +43,7 @@ class Ip_DictElement : public Variable {
std::vector<const VariableValue *> *l) override {
t->m_collections.m_ip_collection->resolveMultiMatches(
m_name, t->m_collections.m_ip_collection_key,
t->m_rules->m_secWebAppId.m_value, l);
t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);
}
std::string m_dictElement;
@ -59,7 +60,7 @@ class Ip_NoDictElement : public Variable {
std::vector<const VariableValue *> *l) override {
t->m_collections.m_ip_collection->resolveMultiMatches("",
t->m_collections.m_ip_collection_key,
t->m_rules->m_secWebAppId.m_value, l);
t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);
}
};
@ -74,9 +75,9 @@ class Ip_DictElementRegexp : public Variable {
void evaluate(Transaction *t,
Rule *rule,
std::vector<const VariableValue *> *l) override {
t->m_collections.m_ip_collection->resolveRegularExpression(m_dictElement,
t->m_collections.m_ip_collection_key,
t->m_rules->m_secWebAppId.m_value, l);
t->m_collections.m_ip_collection->resolveRegularExpression(
m_dictElement, t->m_collections.m_ip_collection_key,
t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);
}
Utils::Regex m_r;
@ -97,7 +98,7 @@ class Ip_DynamicElement : public Variable {
t->m_collections.m_ip_collection->resolveMultiMatches(
string,
t->m_collections.m_ip_collection_key,
t->m_rules->m_secWebAppId.m_value, l);
t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);
}
void del(Transaction *t, std::string k) {

View File

@ -54,7 +54,7 @@ class MatchedVars_NoDictElement : public Variable {
void evaluate(Transaction *transaction,
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableMatchedVars.resolve(l);
transaction->m_variableMatchedVars.resolve(l, m_keyExclusion);
}
};
@ -69,7 +69,7 @@ class MatchedVars_DictElementRegexp : public Variable {
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableMatchedVars.resolveRegularExpression(
&m_r, l);
&m_r, l, m_keyExclusion);
}
Utils::Regex m_r;

View File

@ -54,7 +54,7 @@ class MatchedVarsNames_NoDictElement : public Variable {
void evaluate(Transaction *transaction,
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableMatchedVarsNames.resolve(l);
transaction->m_variableMatchedVarsNames.resolve(l, m_keyExclusion);
}
};
@ -69,7 +69,7 @@ class MatchedVarsNames_DictElementRegexp : public Variable {
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableMatchedVarsNames.resolveRegularExpression(
&m_r, l);
&m_r, l, m_keyExclusion);
}
Utils::Regex m_r;

View File

@ -54,7 +54,7 @@ class MultiPartFileName_NoDictElement : public Variable {
void evaluate(Transaction *transaction,
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableMultipartFileName.resolve(l);
transaction->m_variableMultipartFileName.resolve(l, m_keyExclusion);
}
};
@ -69,7 +69,7 @@ class MultiPartFileName_DictElementRegexp : public Variable {
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableMultipartFileName.resolveRegularExpression(
&m_r, l);
&m_r, l, m_keyExclusion);
}
Utils::Regex m_r;

View File

@ -54,7 +54,7 @@ class MultiPartName_NoDictElement : public Variable {
void evaluate(Transaction *transaction,
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableMultipartName.resolve(l);
transaction->m_variableMultipartName.resolve(l, m_keyExclusion);
}
};
@ -69,7 +69,7 @@ class MultiPartName_DictElementRegexp : public Variable {
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableMultipartName.resolveRegularExpression(
&m_r, l);
&m_r, l, m_keyExclusion);
}
Utils::Regex m_r;

View File

@ -54,7 +54,7 @@ class RequestCookies_NoDictElement : public Variable {
void evaluate(Transaction *transaction,
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableRequestCookies.resolve(l);
transaction->m_variableRequestCookies.resolve(l, m_keyExclusion);
}
};
@ -63,13 +63,15 @@ class RequestCookies_DictElementRegexp : public Variable {
public:
explicit RequestCookies_DictElementRegexp(std::string dictElement)
: Variable("REQUEST_COOKIES:regex(" + dictElement + ")"),
m_r(dictElement) { }
m_r(dictElement) {
m_regex = dictElement;
}
void evaluate(Transaction *transaction,
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableRequestCookies.resolveRegularExpression(
&m_r, l);
&m_r, l, m_keyExclusion);
}
Utils::Regex m_r;

View File

@ -54,7 +54,7 @@ class RequestCookiesNames_NoDictElement : public Variable {
void evaluate(Transaction *transaction,
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableRequestCookiesNames.resolve(l);
transaction->m_variableRequestCookiesNames.resolve(l, m_keyExclusion);
}
};
@ -69,7 +69,7 @@ class RequestCookiesNames_DictElementRegexp : public Variable {
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableRequestCookiesNames.resolveRegularExpression(
&m_r, l);
&m_r, l, m_keyExclusion);
}
Utils::Regex m_r;

View File

@ -54,7 +54,7 @@ class RequestHeaders_NoDictElement : public Variable {
void evaluate(Transaction *transaction,
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableRequestHeaders.resolve(l);
transaction->m_variableRequestHeaders.resolve(l, m_keyExclusion);
}
};
@ -69,7 +69,7 @@ class RequestHeaders_DictElementRegexp : public Variable {
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableRequestHeaders.resolveRegularExpression(
&m_r, l);
&m_r, l, m_keyExclusion);
}
Utils::Regex m_r;

View File

@ -53,7 +53,7 @@ class RequestHeadersNames_NoDictElement : public Variable {
void evaluate(Transaction *transaction,
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableRequestHeadersNames.resolve(l);
transaction->m_variableRequestHeadersNames.resolve(l, m_keyExclusion);
}
};
@ -67,7 +67,7 @@ class RequestHeadersNames_DictElementRegexp : public Variable {
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableRequestHeadersNames.resolveRegularExpression(
&m_r, l);
&m_r, l, m_keyExclusion);
}
Utils::Regex m_r;

View File

@ -14,10 +14,11 @@
*/
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#ifndef SRC_VARIABLES_RESOURCE_H_
#define SRC_VARIABLES_RESOURCE_H_
@ -42,7 +43,7 @@ class Resource_DictElement : public Variable {
std::vector<const VariableValue *> *l) override {
t->m_collections.m_resource_collection->resolveMultiMatches(
m_name, t->m_collections.m_resource_collection_key,
t->m_rules->m_secWebAppId.m_value, l);
t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);
}
std::string m_dictElement;
@ -59,7 +60,7 @@ class Resource_NoDictElement : public Variable {
std::vector<const VariableValue *> *l) override {
t->m_collections.m_resource_collection->resolveMultiMatches(m_name,
t->m_collections.m_resource_collection_key,
t->m_rules->m_secWebAppId.m_value, l);
t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);
}
};
@ -76,7 +77,7 @@ class Resource_DictElementRegexp : public Variable {
std::vector<const VariableValue *> *l) override {
t->m_collections.m_resource_collection->resolveRegularExpression(
m_dictElement, t->m_collections.m_resource_collection_key,
t->m_rules->m_secWebAppId.m_value, l);
t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);
}
Utils::Regex m_r;
@ -97,7 +98,7 @@ class Resource_DynamicElement : public Variable {
t->m_collections.m_resource_collection->resolveMultiMatches(
string,
t->m_collections.m_resource_collection_key,
t->m_rules->m_secWebAppId.m_value, l);
t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);
}
void del(Transaction *t, std::string k) {

View File

@ -54,7 +54,7 @@ class ResponseHeaders_NoDictElement : public Variable {
void evaluate(Transaction *transaction,
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableResponseHeaders.resolve(l);
transaction->m_variableResponseHeaders.resolve(l, m_keyExclusion);
}
};
@ -69,7 +69,7 @@ class ResponseHeaders_DictElementRegexp : public Variable {
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableResponseHeaders.resolveRegularExpression(
&m_r, l);
&m_r, l, m_keyExclusion);
}
Utils::Regex m_r;

View File

@ -53,7 +53,7 @@ class ResponseHeadersNames_NoDictElement : public Variable {
void evaluate(Transaction *transaction,
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableResponseHeadersNames.resolve(l);
transaction->m_variableResponseHeadersNames.resolve(l, m_keyExclusion);
}
};
@ -67,7 +67,7 @@ class ResponseHeadersNames_DictElementRegexp : public Variable {
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableResponseHeadersNames.resolveRegularExpression(
&m_r, l);
&m_r, l, m_keyExclusion);
}
Utils::Regex m_r;

View File

@ -52,7 +52,7 @@ class Rule_NoDictElement : public Variable {
void evaluate(Transaction *transaction,
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableRule.resolve(l);
transaction->m_variableRule.resolve(l, m_keyExclusion);
}
};
@ -67,7 +67,7 @@ class Rule_DictElementRegexp : public Variable {
Rule *rule,
std::vector<const VariableValue *> *l) override {
transaction->m_variableRule.resolveRegularExpression(
&m_r, l);
&m_r, l, m_keyExclusion);
}
Utils::Regex m_r;

View File

@ -14,10 +14,11 @@
*/
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#ifndef SRC_VARIABLES_SESSION_H_
#define SRC_VARIABLES_SESSION_H_
@ -42,7 +43,7 @@ class Session_DictElement : public Variable {
std::vector<const VariableValue *> *l) override {
t->m_collections.m_session_collection->resolveMultiMatches(
m_name, t->m_collections.m_session_collection_key,
t->m_rules->m_secWebAppId.m_value, l);
t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);
}
std::string m_dictElement;
@ -59,7 +60,7 @@ class Session_NoDictElement : public Variable {
std::vector<const VariableValue *> *l) override {
t->m_collections.m_session_collection->resolveMultiMatches("",
t->m_collections.m_session_collection_key,
t->m_rules->m_secWebAppId.m_value, l);
t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);
}
};
@ -74,9 +75,9 @@ class Session_DictElementRegexp : public Variable {
void evaluate(Transaction *t,
Rule *rule,
std::vector<const VariableValue *> *l) override {
t->m_collections.m_session_collection->resolveRegularExpression(m_dictElement,
t->m_collections.m_session_collection_key,
t->m_rules->m_secWebAppId.m_value, l);
t->m_collections.m_session_collection->resolveRegularExpression(
m_dictElement, t->m_collections.m_session_collection_key,
t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);
}
Utils::Regex m_r;
@ -97,7 +98,7 @@ class Session_DynamicElement : public Variable {
t->m_collections.m_session_collection->resolveMultiMatches(
string,
t->m_collections.m_session_collection_key,
t->m_rules->m_secWebAppId.m_value, l);
t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);
}
void del(Transaction *t, std::string k) {

View File

@ -18,6 +18,7 @@
#include <vector>
#include <list>
#include <utility>
#include <memory>
#ifndef SRC_VARIABLES_TX_H_
#define SRC_VARIABLES_TX_H_
@ -41,7 +42,7 @@ class Tx_DictElement : public Variable {
Rule *rule,
std::vector<const VariableValue *> *l) override {
t->m_collections.m_tx_collection->resolveMultiMatches(
m_name, l);
m_name, l, m_keyExclusion);
}
std::string m_dictElement;
@ -56,7 +57,8 @@ class Tx_NoDictElement : public Variable {
void evaluate(Transaction *t,
Rule *rule,
std::vector<const VariableValue *> *l) override {
t->m_collections.m_tx_collection->resolveMultiMatches("", l);
t->m_collections.m_tx_collection->resolveMultiMatches("", l,
m_keyExclusion);
}
};
@ -72,7 +74,7 @@ class Tx_DictElementRegexp : public Variable {
Rule *rule,
std::vector<const VariableValue *> *l) override {
t->m_collections.m_tx_collection->resolveRegularExpression(
m_dictElement, l);
m_dictElement, l, m_keyExclusion);
}
Utils::Regex m_r;
@ -90,7 +92,8 @@ class Tx_DynamicElement : public Variable {
Rule *rule,
std::vector<const VariableValue *> *l) override {
std::string string = m_string->evaluate(t);
t->m_collections.m_tx_collection->resolveMultiMatches(string, l);
t->m_collections.m_tx_collection->resolveMultiMatches(string, l,
m_keyExclusion);
}
void del(Transaction *t, std::string k) {

View File

@ -14,10 +14,11 @@
*/
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#ifndef SRC_VARIABLES_USER_H_
#define SRC_VARIABLES_USER_H_
@ -42,7 +43,7 @@ class User_DictElement : public Variable {
std::vector<const VariableValue *> *l) override {
t->m_collections.m_user_collection->resolveMultiMatches(
m_name, t->m_collections.m_user_collection_key,
t->m_rules->m_secWebAppId.m_value, l);
t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);
}
std::string m_dictElement;
@ -59,7 +60,7 @@ class User_NoDictElement : public Variable {
std::vector<const VariableValue *> *l) override {
t->m_collections.m_user_collection->resolveMultiMatches(m_name,
t->m_collections.m_user_collection_key,
t->m_rules->m_secWebAppId.m_value, l);
t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);
}
};
@ -76,7 +77,7 @@ class User_DictElementRegexp : public Variable {
std::vector<const VariableValue *> *l) override {
t->m_collections.m_user_collection->resolveRegularExpression(
m_dictElement, t->m_collections.m_user_collection_key,
t->m_rules->m_secWebAppId.m_value, l);
t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);
}
Utils::Regex m_r;
@ -97,7 +98,7 @@ class User_DynamicElement : public Variable {
t->m_collections.m_user_collection->resolveMultiMatches(
string,
t->m_collections.m_user_collection_key,
t->m_rules->m_secWebAppId.m_value, l);
t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);
}
void del(Transaction *t, std::string k) {

View File

@ -32,7 +32,8 @@ Variable::Variable(std::string name)
: m_name(name),
m_collectionName(""),
m_isExclusion(false),
m_isCount(false) {
m_isCount(false),
m_regex("") {
size_t a = m_name.find(":");
if (a == std::string::npos) {
a = m_name.find(".");
@ -40,7 +41,8 @@ Variable::Variable(std::string name)
if (a != std::string::npos) {
m_collectionName = utils::string::toupper(std::string(m_name, 0, a));
m_name = std::string(m_name, a + 1, m_name.size());
m_fullName = std::make_shared<std::string>(m_collectionName + ":" + m_name);
m_fullName = std::make_shared<std::string>(m_collectionName
+ ":" + m_name);
} else {
m_fullName = std::make_shared<std::string>(m_name);
m_collectionName = m_name;
@ -49,6 +51,9 @@ Variable::Variable(std::string name)
}
std::string Variable::to_s(
std::vector<Variable *> *variables) {
std::string ret;

View File

@ -13,12 +13,12 @@
*
*/
#include <vector>
#include <string>
#include <list>
#include <utility>
#include <memory>
#include <exception>
#include <list>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "modsecurity/transaction.h"
#include "modsecurity/rule.h"
@ -35,6 +35,55 @@ class Transaction;
namespace Variables {
class KeyExclusion {
public:
virtual bool match(std::string &a) = 0;
};
// FIXME: use pre built regex.
class KeyExclusionRegex : public KeyExclusion {
public:
KeyExclusionRegex(std::string &re)
: m_re(re) { };
bool match(std::string &a) override {
return m_re.searchAll(a).size() > 0;
}
Utils::Regex m_re;
};
class KeyExclusionString : public KeyExclusion {
public:
KeyExclusionString(std::string &a)
: m_key(utils::string::toupper(a)) { };
bool match(std::string &a) override {
return a.size() == m_key.size() && std::equal(a.begin(), a.end(), m_key.begin(),
[](char aa, char bb) {
return (char) toupper(aa) == (char) bb;
});
}
std::string m_key;
};
class KeyExclusions : public std::deque<std::unique_ptr<KeyExclusion>> {
public:
bool toOmit(std::string a) {
for (auto &z : *this) {
if (z->match(a)) {
return true;
}
}
return false;
}
};
class Variable {
public:
explicit Variable(std::string _name);
@ -54,6 +103,34 @@ class Variable {
});
}
bool inline belongsToCollection(Variable *var) {
return m_collectionName.size() == var->m_collectionName.size()
&& std::equal(m_collectionName.begin(), m_collectionName.end(), var->m_collectionName.begin(),
[](char aa, char bb) {
return toupper(aa) == bb;
});
}
void inline addsKeyExclusion(Variable *v) {
if (v->m_regex.empty()) {
std::unique_ptr<KeyExclusion> r(new KeyExclusionString(v->m_name));
m_keyExclusion.push_back(std::move(r));
} else {
std::unique_ptr<KeyExclusion> r(new KeyExclusionRegex(v->m_regex));
m_keyExclusion.push_back(std::move(r));
}
}
bool operator==(const Variable& b) {
return m_collectionName == b.m_collectionName &&
m_name == b.m_name &&
*m_fullName == *b.m_fullName;
}
static void stringMatchResolveMulti(Transaction *t,
const std::string &variable,
std::vector<const VariableValue *> *l) {
@ -425,6 +502,9 @@ class Variable {
std::string m_name;
std::string m_collectionName;
std::shared_ptr<std::string> m_fullName;
std::string m_regex;
KeyExclusions m_keyExclusion;
bool m_isExclusion;
bool m_isCount;
@ -437,6 +517,7 @@ class VariableModificatorExclusion : public Variable {
: Variable(*var->m_fullName.get()),
m_var(std::move(var)) {
m_isExclusion = true;
m_regex = m_var->m_regex;
}
void evaluate(Transaction *t,

View File

@ -137,8 +137,10 @@ void XML::evaluate(Transaction *t,
std::string *a = new std::string(content);
VariableValue *var = new VariableValue(m_fullName,
a);
if (!m_keyExclusion.toOmit(*m_fullName)) {
l->push_back(var);
}
delete a;
l->push_back(var);
xmlFree(content);
}
}

View File

@ -3,7 +3,7 @@
"enabled": 1,
"version_min": 209000,
"version_max": -1,
"title": "Invalid actions break CRS 3.1 on rule 912160",
"title": "Invalid actions break CRS 3.1 on rule 912160 - 1",
"url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/1830",
"client": {
"ip": "200.249.12.31",
@ -50,7 +50,7 @@
"enabled": 1,
"version_min": 209000,
"version_max": -1,
"title": "Invalid actions break CRS 3.1 on rule 912160",
"title": "Invalid actions break CRS 3.1 on rule 912160 - 2",
"url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/1830",
"client": {
"ip": "200.249.12.31",
@ -100,7 +100,7 @@
"enabled": 1,
"version_min": 209000,
"version_max": -1,
"title": "Invalid actions break CRS 3.1 on rule 912160",
"title": "Invalid actions break CRS 3.1 on rule 912160 - 3",
"url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/1830",
"client": {
"ip": "200.249.12.31",
@ -149,7 +149,7 @@
"enabled": 1,
"version_min": 209000,
"version_max": -1,
"title": "Invalid actions break CRS 3.1 on rule 912160",
"title": "Invalid actions break CRS 3.1 on rule 912160 - 4",
"url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/1830",
"client": {
"ip": "200.249.12.31",

View File

@ -48,12 +48,13 @@
},
"expected":{
"audit_log":"",
"debug_log":"Variable: REQUEST_HEADERS:Accept is part of the exclusion list, skipping...",
"error_log":""
"debug_log":"",
"error_log":"",
"http_code":200
},
"rules":[
"SecRuleEngine On",
"SecRule REQUEST_HEADERS|!REQUEST_HEADERS:Accept|!REMOTE_HOST \"@contains test \" \"id:1,t:lowercase,t:none\""
"SecRule REQUEST_HEADERS|!REQUEST_HEADERS:Accept|!REMOTE_HOST \"@contains html\" \"id:1,t:lowercase,t:none,block,deny,status:300\""
]
},
{
@ -105,12 +106,13 @@
},
"expected":{
"audit_log":"",
"debug_log":"Variable: REQUEST_HEADERS:Accept-Encoding is part of the exclusion list, skipping...",
"error_log":""
"debug_log":"",
"error_log":"",
"http_code": 200
},
"rules":[
"SecRuleEngine On",
"SecRule REQUEST_HEADERS|!REQUEST_HEADERS \"@contains test \" \"id:1,t:lowercase,t:none\""
"SecRule REQUEST_HEADERS|!REQUEST_HEADERS \"@contains html\" \"id:1,t:lowercase,t:none,block,deny,status:300\""
]
}
]