Makes RULE collection to be resolved inside a macro expansion

This commit is contained in:
Felipe Zimmerle
2016-07-21 13:09:22 -03:00
parent 5514b66145
commit 5d64f73817
6 changed files with 143 additions and 13 deletions

View File

@@ -90,9 +90,9 @@ bool SetVar::init(std::string *error) {
bool SetVar::evaluate(Rule *rule, Transaction *transm_parser_payload) {
std::string targetValue;
std::string m_variableNameExpanded = MacroExpansion::expand(m_variableName,
transm_parser_payload);
rule, transm_parser_payload);
std::string resolvedPre = MacroExpansion::expand(m_predicate,
transm_parser_payload);
rule, transm_parser_payload);
if (m_operation == setOperation) {
targetValue = resolvedPre;

View File

@@ -81,7 +81,6 @@ void Collections::storeOrUpdateFirst(const std::string& collectionName,
return;
}
if (tolower(collectionName) == "session"
&& !m_session_collection_key.empty()) {
m_session_collection->storeOrUpdateFirst(collectionName + ":"

View File

@@ -15,6 +15,11 @@
#include "src/macro_expansion.h"
#include "modsecurity/transaction.h"
#include "modsecurity/collection/variable.h"
#include "src/variables/rule.h"
#include "src/variables/tx.h"
#include "src/variables/highest_severity.h"
namespace modsecurity {
@@ -35,8 +40,15 @@ std::string MacroExpansion::expandKeepOriginal(const std::string& input,
std::string MacroExpansion::expand(const std::string& input,
Transaction *transaction) {
return expand(input, NULL, transaction);
}
std::string MacroExpansion::expand(const std::string& input,
modsecurity::Rule *rule, Transaction *transaction) {
std::string res;
size_t pos = input.find("%{");
std::string v;
if (pos != std::string::npos) {
res = input;
@@ -59,7 +71,27 @@ std::string MacroExpansion::expand(const std::string& input,
std::string col = std::string(variable, 0, collection);
std::string var = std::string(variable, collection + 1,
variable.length() - (collection + 1));
variableValue = transaction->m_collections.resolveFirst(col, var);
if (col == "RULE") {
if (rule == NULL) {
transaction->debug(9, "macro expansion: cannot resolve " \
"RULE variable without the Rule object");
goto ops;
}
modsecurity::Variables::Rule r("RULE:" + var);
std::vector<const collection::Variable *> l;
r.evaluateInternal(transaction, rule, &l);
if (l.size() > 0) {
v = l[0]->m_value;
variableValue = &v;
}
for (auto *i : l) {
delete i;
}
} else {
variableValue = transaction->m_collections.resolveFirst(col,
var);
}
}
res.erase(start, end - start + 1);
@@ -70,7 +102,7 @@ std::string MacroExpansion::expand(const std::string& input,
if (variableValue != NULL) {
res.insert(start, *variableValue);
}
ops:
pos = res.find("%{");
}

View File

@@ -33,6 +33,8 @@ class MacroExpansion {
static std::string expand(const std::string& input,
Transaction *transaction);
static std::string expand(const std::string& input,
modsecurity::Rule *r, Transaction *transaction);
static std::string expandKeepOriginal(const std::string& input,
Transaction *transaction);
};

View File

@@ -44,6 +44,7 @@
#include "src/actions/xmlns.h"
#include "src/actions/log_data.h"
#include "src/actions/msg.h"
#include "src/utils.h"
namespace modsecurity {
namespace Variables {
@@ -52,6 +53,7 @@ void Rule::evaluateInternal(Transaction *t,
modsecurity::Rule *rule,
std::vector<const collection::Variable *> *l) {
std::map<std::string, std::string> envs;
std::string m_name_upper = toupper(m_name);
// id
envs.insert(std::pair<std::string, std::string>("RULE:id",
@@ -86,14 +88,17 @@ void Rule::evaluateInternal(Transaction *t,
for (actions::Action *i : acts) {
actions::Msg *a = reinterpret_cast<actions::Msg *>(i);
if (a) {
std::string data = a->data(t);
envs.insert(std::pair<std::string, std::string>("RULE:msg",
a->data(t)));
data));
}
}
for (auto& x : envs) {
if ((x.first.substr(0, m_name.size() + 1).compare(m_name + ":") != 0)
&& (x.first != m_name)) {
std::string xup = toupper(x.first);
if ((xup.substr(0, m_name_upper.size() + 1)
.compare(m_name_upper + ":") != 0)
&& (xup != m_name_upper)) {
continue;
}
l->push_back(new collection::Variable(x.first, x.second));