Fix RULE lookup in chained rules.

This commit is contained in:
Felipe Zimmerle 2018-10-15 16:42:36 -03:00
parent 120108fd33
commit 8bda7c0a45
No known key found for this signature in database
GPG Key ID: E6DFB08CE8B11277
4 changed files with 59 additions and 24 deletions

View File

@ -140,7 +140,8 @@ class Rule {
int m_phase; int m_phase;
modsecurity::Variables::Variables *m_variables; modsecurity::Variables::Variables *m_variables;
operators::Operator *m_op; operators::Operator *m_op;
Rule *m_chainedRule; Rule *m_chainedRuleChild;
Rule *m_chainedRuleParent;
std::string m_fileName; std::string m_fileName;
std::string m_marker; std::string m_marker;
std::string m_rev; std::string m_rev;

View File

@ -78,9 +78,10 @@ int Driver::addSecRule(Rule *rule) {
} }
if (lastRule && lastRule->m_chained) { if (lastRule && lastRule->m_chained) {
if (lastRule->m_chainedRule == NULL) { if (lastRule->m_chainedRuleChild == NULL) {
rule->m_phase = lastRule->m_phase; rule->m_phase = lastRule->m_phase;
lastRule->m_chainedRule = rule; lastRule->m_chainedRuleChild = rule;
rule->m_chainedRuleParent = lastRule;
if (rule->m_theDisruptiveAction) { if (rule->m_theDisruptiveAction) {
m_parserError << "Disruptive actions can only be specified by"; m_parserError << "Disruptive actions can only be specified by";
m_parserError << " chain starter rules."; m_parserError << " chain starter rules.";
@ -88,12 +89,13 @@ int Driver::addSecRule(Rule *rule) {
} }
return true; return true;
} else { } else {
Rule *a = lastRule->m_chainedRule; Rule *a = lastRule->m_chainedRuleChild;
while (a->m_chained && a->m_chainedRule != NULL) { while (a->m_chained && a->m_chainedRuleChild != NULL) {
a = a->m_chainedRule; a = a->m_chainedRuleChild;
} }
if (a->m_chained && a->m_chainedRule == NULL) { if (a->m_chained && a->m_chainedRuleChild == NULL) {
a->m_chainedRule = rule; a->m_chainedRuleChild = rule;
rule->m_chainedRuleParent = a;
if (a->m_theDisruptiveAction) { if (a->m_theDisruptiveAction) {
m_parserError << "Disruptive actions can only be "; m_parserError << "Disruptive actions can only be ";
m_parserError << "specified by chain starter rules."; m_parserError << "specified by chain starter rules.";

View File

@ -57,7 +57,7 @@ Rule::Rule(std::string marker)
m_actionsSetVar(), m_actionsSetVar(),
m_actionsTag(), m_actionsTag(),
m_chained(false), m_chained(false),
m_chainedRule(NULL), m_chainedRuleChild(NULL),
m_fileName(""), m_fileName(""),
m_lineNumber(0), m_lineNumber(0),
m_marker(marker), m_marker(marker),
@ -91,7 +91,8 @@ Rule::Rule(Operator *_op,
m_actionsSetVar(), m_actionsSetVar(),
m_actionsTag(), m_actionsTag(),
m_chained(false), m_chained(false),
m_chainedRule(NULL), m_chainedRuleChild(NULL),
m_chainedRuleParent(NULL),
m_fileName(fileName), m_fileName(fileName),
m_lineNumber(lineNumber), m_lineNumber(lineNumber),
m_marker(""), m_marker(""),
@ -146,8 +147,8 @@ Rule::~Rule() {
delete m_variables; delete m_variables;
} }
if (m_chainedRule != NULL) { if (m_chainedRuleChild != NULL) {
delete m_chainedRule; delete m_chainedRuleChild;
} }
} }
@ -793,7 +794,7 @@ bool Rule::evaluate(Transaction *trans,
goto end_exec; goto end_exec;
} }
if (this->m_chainedRule == NULL) { if (this->m_chainedRuleChild == NULL) {
#ifndef NO_LOGS #ifndef NO_LOGS
trans->debug(4, "Rule is marked as chained but there " \ trans->debug(4, "Rule is marked as chained but there " \
"isn't a subsequent rule."); "isn't a subsequent rule.");
@ -804,7 +805,7 @@ bool Rule::evaluate(Transaction *trans,
#ifndef NO_LOGS #ifndef NO_LOGS
trans->debug(4, "Executing chained rule."); trans->debug(4, "Executing chained rule.");
#endif #endif
recursiveGlobalRet = this->m_chainedRule->evaluate(trans, ruleMessage); recursiveGlobalRet = this->m_chainedRuleChild->evaluate(trans, ruleMessage);
if (recursiveGlobalRet == true) { if (recursiveGlobalRet == true) {
goto end_exec; goto end_exec;

View File

@ -40,11 +40,17 @@ class Rule_DictElement : public VariableDictElement { \
static void id(Transaction *t, static void id(Transaction *t,
Rule *rule, Rule *rule,
std::vector<const VariableValue *> *l) { std::vector<const VariableValue *> *l) {
if (!rule) { Rule *r = rule;
while (r && r->m_ruleId == 0) {
r = r->m_chainedRuleParent;
}
if (!r || r->m_ruleId == 0) {
return; return;
} }
std::unique_ptr<VariableOrigin> origin(new VariableOrigin()); std::unique_ptr<VariableOrigin> origin(new VariableOrigin());
std::string *a = new std::string(std::to_string(rule->m_ruleId)); std::string *a = new std::string(std::to_string(r->m_ruleId));
VariableValue *var = new VariableValue( VariableValue *var = new VariableValue(
std::make_shared<std::string>("RULE:id"), std::make_shared<std::string>("RULE:id"),
a a
@ -60,11 +66,18 @@ class Rule_DictElement : public VariableDictElement { \
static void rev(Transaction *t, static void rev(Transaction *t,
Rule *rule, Rule *rule,
std::vector<const VariableValue *> *l) { std::vector<const VariableValue *> *l) {
if (!rule) { Rule *r = rule;
while (r && r->m_rev.empty()) {
r = r->m_chainedRuleParent;
}
if (!r) {
return; return;
} }
std::unique_ptr<VariableOrigin> origin(new VariableOrigin()); std::unique_ptr<VariableOrigin> origin(new VariableOrigin());
std::string *a = new std::string(rule->m_rev); std::string *a = new std::string(r->m_rev);
VariableValue *var = new VariableValue( VariableValue *var = new VariableValue(
std::make_shared<std::string>("RULE:rev"), std::make_shared<std::string>("RULE:rev"),
a a
@ -80,9 +93,15 @@ class Rule_DictElement : public VariableDictElement { \
static void severity(Transaction *t, static void severity(Transaction *t,
Rule *rule, Rule *rule,
std::vector<const VariableValue *> *l) { std::vector<const VariableValue *> *l) {
if (rule && rule->m_severity) { Rule *r = rule;
while (r && !r->m_severity) {
r = r->m_chainedRuleParent;
}
if (r && r->m_severity) {
std::unique_ptr<VariableOrigin> origin(new VariableOrigin()); std::unique_ptr<VariableOrigin> origin(new VariableOrigin());
std::string *a = new std::string(std::to_string(rule->m_severity->m_severity)); std::string *a = new std::string(std::to_string(r->m_severity->m_severity));
VariableValue *var = new VariableValue( VariableValue *var = new VariableValue(
std::make_shared<std::string>("RULE:severity"), std::make_shared<std::string>("RULE:severity"),
a a
@ -99,9 +118,15 @@ class Rule_DictElement : public VariableDictElement { \
static void logData(Transaction *t, static void logData(Transaction *t,
Rule *rule, Rule *rule,
std::vector<const VariableValue *> *l) { std::vector<const VariableValue *> *l) {
if (rule && rule->m_logData) { Rule *r = rule;
while (r && !r->m_logData) {
r = r->m_chainedRuleParent;
}
if (r && r->m_logData) {
std::unique_ptr<VariableOrigin> origin(new VariableOrigin()); std::unique_ptr<VariableOrigin> origin(new VariableOrigin());
std::string *a = new std::string(rule->m_logData->data(t)); std::string *a = new std::string(r->m_logData->data(t));
VariableValue *var = new VariableValue( VariableValue *var = new VariableValue(
std::make_shared<std::string>("RULE:logdata"), std::make_shared<std::string>("RULE:logdata"),
a a
@ -117,9 +142,15 @@ class Rule_DictElement : public VariableDictElement { \
static void msg(Transaction *t, static void msg(Transaction *t,
Rule *rule, Rule *rule,
std::vector<const VariableValue *> *l) { std::vector<const VariableValue *> *l) {
if (rule && rule->m_msg) { Rule *r = rule;
while (r && !r->m_msg) {
r = r->m_chainedRuleParent;
}
if (r && r->m_msg) {
std::unique_ptr<VariableOrigin> origin(new VariableOrigin()); std::unique_ptr<VariableOrigin> origin(new VariableOrigin());
std::string *a = new std::string(rule->m_msg->data(t)); std::string *a = new std::string(r->m_msg->data(t));
VariableValue *var = new VariableValue( VariableValue *var = new VariableValue(
std::make_shared<std::string>("RULE:msg"), std::make_shared<std::string>("RULE:msg"),
a a