Adds full support to UpdateActionById.

Issue #1800
This commit is contained in:
Felipe Zimmerle
2018-10-04 01:06:28 -03:00
parent 3e8e28da48
commit 85ecd190d9
17 changed files with 963 additions and 719 deletions

View File

@@ -106,6 +106,7 @@ ACTIONS = \
actions/accuracy.cc \
actions/action.cc \
actions/audit_log.cc \
actions/block.cc \
actions/capture.cc \
actions/chain.cc \
actions/ctl/audit_log_parts.cc \
@@ -119,7 +120,6 @@ ACTIONS = \
actions/ctl/rule_remove_by_tag.cc \
actions/ctl/request_body_access.cc\
actions/disruptive/allow.cc \
actions/disruptive/block.cc \
actions/disruptive/deny.cc \
actions/disruptive/redirect.cc \
actions/disruptive/pass.cc \

View File

@@ -22,7 +22,7 @@
#include "modsecurity/rule.h"
#include "src/utils/string.h"
#include "src/actions/disruptive/block.h"
#include "src/actions/block.h"
#include "src/actions/chain.h"
#include "src/actions/disruptive/deny.h"
#include "src/actions/disruptive/redirect.h"

View File

@@ -13,7 +13,7 @@
*
*/
#include "src/actions/disruptive/block.h"
#include "src/actions/block.h"
#include <iostream>
#include <string>
@@ -27,7 +27,6 @@
namespace modsecurity {
namespace actions {
namespace disruptive {
bool Block::evaluate(Rule *rule, Transaction *transaction,
@@ -37,8 +36,7 @@ bool Block::evaluate(Rule *rule, Transaction *transaction,
#endif
for (Action *a : transaction->m_rules->m_defaultActions[rule->m_phase]) {
if (a->isDisruptive() == false
|| dynamic_cast<actions::disruptive::Block *>(a) != NULL) {
if (a->isDisruptive() == false) {
continue;
}
a->evaluate(rule, transaction, rm);
@@ -48,6 +46,5 @@ bool Block::evaluate(Rule *rule, Transaction *transaction,
}
} // namespace disruptive
} // namespace actions
} // namespace modsecurity

View File

@@ -29,7 +29,6 @@ namespace modsecurity {
class Transaction;
namespace actions {
namespace disruptive {
class Block : public Action {
@@ -38,11 +37,9 @@ class Block : public Action {
bool evaluate(Rule *rule, Transaction *transaction,
std::shared_ptr<RuleMessage> rm) override;
bool isDisruptive() override { return true; }
};
} // namespace disruptive
} // namespace actions
} // namespace modsecurity
#endif

View File

@@ -81,7 +81,7 @@ int Driver::addSecRule(Rule *rule) {
if (lastRule->m_chainedRule == NULL) {
rule->m_phase = lastRule->m_phase;
lastRule->m_chainedRule = rule;
if (rule->m_containsStaticDisruptiveAction) {
if (rule->m_theDisruptiveAction) {
m_parserError << "Disruptive actions can only be specified by";
m_parserError << " chain starter rules.";
return false;
@@ -94,7 +94,7 @@ int Driver::addSecRule(Rule *rule) {
}
if (a->m_chained && a->m_chainedRule == NULL) {
a->m_chainedRule = rule;
if (a->m_containsStaticDisruptiveAction) {
if (a->m_theDisruptiveAction) {
m_parserError << "Disruptive actions can only be ";
m_parserError << "specified by chain starter rules.";
return false;

File diff suppressed because it is too large Load Diff

View File

@@ -55,6 +55,7 @@ class Driver;
#include "src/actions/accuracy.h"
#include "src/actions/audit_log.h"
#include "src/actions/block.h"
#include "src/actions/capture.h"
#include "src/actions/chain.h"
#include "src/actions/ctl/audit_log_parts.h"
@@ -69,7 +70,6 @@ class Driver;
#include "src/actions/ctl/rule_remove_target_by_tag.h"
#include "src/actions/data/status.h"
#include "src/actions/disruptive/allow.h"
#include "src/actions/disruptive/block.h"
#include "src/actions/disruptive/deny.h"
#include "src/actions/disruptive/pass.h"
#include "src/actions/disruptive/redirect.h"

View File

@@ -21,6 +21,7 @@ class Driver;
#include "src/actions/accuracy.h"
#include "src/actions/audit_log.h"
#include "src/actions/block.h"
#include "src/actions/capture.h"
#include "src/actions/chain.h"
#include "src/actions/ctl/audit_log_parts.h"
@@ -35,7 +36,6 @@ class Driver;
#include "src/actions/ctl/rule_remove_target_by_tag.h"
#include "src/actions/data/status.h"
#include "src/actions/disruptive/allow.h"
#include "src/actions/disruptive/block.h"
#include "src/actions/disruptive/deny.h"
#include "src/actions/disruptive/pass.h"
#include "src/actions/disruptive/redirect.h"
@@ -1188,7 +1188,7 @@ expression:
int secRuleDefinedPhase = -1;
for (actions::Action *a : *actions) {
actions::Phase *phase = dynamic_cast<actions::Phase *>(a);
if (a->isDisruptive() == true && dynamic_cast<actions::disruptive::Block *>(a) == NULL) {
if (a->isDisruptive() == true && dynamic_cast<actions::Block *>(a) == NULL) {
hasDisruptive = true;
}
if (phase != NULL) {
@@ -1522,8 +1522,6 @@ expression:
driver.error(@0, ss.str());
YYERROR;
}
YYERROR;
}
/* Debug log: start */
| CONFIG_DIR_DEBUG_LVL
@@ -2561,7 +2559,7 @@ act:
}
| ACTION_BLOCK
{
ACTION_CONTAINER($$, new actions::disruptive::Block($1));
ACTION_CONTAINER($$, new actions::Block($1));
}
| ACTION_CAPTURE
{

View File

@@ -38,7 +38,7 @@
#include "src/actions/capture.h"
#include "src/actions/multi_match.h"
#include "src/actions/set_var.h"
#include "src/actions/disruptive/block.h"
#include "src/actions/block.h"
#include "src/variables/variable.h"
@@ -71,7 +71,7 @@ Rule::Rule(std::string marker)
m_ver(""),
m_unconditional(false),
m_referenceCount(1),
m_containsStaticDisruptiveAction(false),
m_theDisruptiveAction(nullptr),
m_containsStaticBlockAction(false),
m_containsCaptureAction(false),
m_containsMultiMatchAction(false),
@@ -105,7 +105,7 @@ Rule::Rule(Operator *_op,
m_ver(""),
m_unconditional(false),
m_referenceCount(1),
m_containsStaticDisruptiveAction(false),
m_theDisruptiveAction(nullptr),
m_containsStaticBlockAction(false),
m_containsCaptureAction(false),
m_containsMultiMatchAction(false),
@@ -180,12 +180,15 @@ void Rule::organizeActions(std::vector<Action *> *actions) {
dynamic_cast<actions::SetVar *>(a));
} else if (dynamic_cast<actions::Tag *>(a)) {
m_actionsTag.push_back(dynamic_cast<actions::Tag *>(a));
} else if (dynamic_cast<actions::disruptive::Block *>(a)) {
} else if (dynamic_cast<actions::Block *>(a)) {
m_actionsRuntimePos.push_back(a);
m_containsStaticBlockAction = true;
} else if (a->isDisruptive() == true) {
m_actionsRuntimePos.push_back(a);
m_containsStaticDisruptiveAction = true;
if (m_theDisruptiveAction != nullptr) {
delete m_theDisruptiveAction;
m_theDisruptiveAction = nullptr;
}
m_theDisruptiveAction = a;
} else {
m_actionsRuntimePos.push_back(a);
}
@@ -231,6 +234,10 @@ void Rule::cleanUpActions() {
m_actionsTag.pop_back();
delete a;
}
if (m_theDisruptiveAction != nullptr) {
delete m_theDisruptiveAction;
m_theDisruptiveAction = nullptr;
}
}
@@ -599,12 +606,15 @@ void Rule::executeAction(Transaction *trans,
void Rule::executeActionsAfterFullMatch(Transaction *trans,
bool containsBlock, std::shared_ptr<RuleMessage> ruleMessage) {
bool disruptiveAlreadyExecuted = false;
for (Action *a : trans->m_rules->m_defaultActions[this->m_phase]) {
if (a->action_kind != actions::Action::RunTimeOnlyIfMatchKind) {
continue;
}
executeAction(trans, containsBlock, ruleMessage, a, true);
if (!a->isDisruptive()) {
executeAction(trans, containsBlock, ruleMessage, a, true);
}
}
for (actions::Tag *a : this->m_actionsTag) {
@@ -615,9 +625,6 @@ void Rule::executeActionsAfterFullMatch(Transaction *trans,
a->evaluate(this, trans, ruleMessage);
}
for (Action *a : this->m_actionsRuntimePos) {
executeAction(trans, containsBlock, ruleMessage, a, false);
}
for (auto &b :
trans->m_rules->m_exceptions.m_action_pos_update_target_by_id) {
if (m_ruleId != b.first) {
@@ -625,6 +632,18 @@ void Rule::executeActionsAfterFullMatch(Transaction *trans,
}
actions::Action *a = dynamic_cast<actions::Action*>(b.second.get());
executeAction(trans, containsBlock, ruleMessage, a, false);
disruptiveAlreadyExecuted = true;
}
for (Action *a : this->m_actionsRuntimePos) {
if (!a->isDisruptive()
&& !(disruptiveAlreadyExecuted
&& dynamic_cast<actions::Block *>(a))) {
executeAction(trans, containsBlock, ruleMessage, a, false);
}
}
if (!disruptiveAlreadyExecuted && m_theDisruptiveAction != nullptr) {
executeAction(trans, containsBlock, ruleMessage,
m_theDisruptiveAction, false);
}
}

View File

@@ -238,6 +238,20 @@ bool RulesExceptions::merge(RulesExceptions *from) {
std::move(p.second)));
}
for (auto &p : from->m_action_pos_update_target_by_id) {
m_action_pos_update_target_by_id.emplace(
std::pair<double,
std::unique_ptr<actions::Action>>(p.first,
std::move(p.second)));
}
for (auto &p : from->m_action_pre_update_target_by_id) {
m_action_pre_update_target_by_id.emplace(
std::pair<double,
std::unique_ptr<actions::Action>>(p.first,
std::move(p.second)));
}
for (auto &p : from->m_remove_rule_by_msg) {
m_remove_rule_by_msg.push_back(p);
}