mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-09-30 19:47:47 +03:00
Refactoring: how to report to error logs
This commit is contained in:
@@ -67,7 +67,6 @@ class Action {
|
|||||||
}
|
}
|
||||||
virtual bool init(std::string *error) { return true; }
|
virtual bool init(std::string *error) { return true; }
|
||||||
virtual bool isDisruptive() { return false; }
|
virtual bool isDisruptive() { return false; }
|
||||||
virtual void fillIntervention(ModSecurityIntervention *intervention);
|
|
||||||
static Action *instantiate(const std::string& name);
|
static Action *instantiate(const std::string& name);
|
||||||
|
|
||||||
|
|
||||||
|
@@ -18,6 +18,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <cstring>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef HEADERS_MODSECURITY_RULE_MESSAGE_H_
|
#ifndef HEADERS_MODSECURITY_RULE_MESSAGE_H_
|
||||||
@@ -50,6 +51,7 @@ class RuleMessage {
|
|||||||
{ }
|
{ }
|
||||||
|
|
||||||
std::string errorLog(Transaction *trans);
|
std::string errorLog(Transaction *trans);
|
||||||
|
std::string disruptiveErrorLog(Transaction *trans, std::string log2);
|
||||||
|
|
||||||
|
|
||||||
std::string m_match;
|
std::string m_match;
|
||||||
@@ -65,7 +67,6 @@ class RuleMessage {
|
|||||||
int m_accuracy;
|
int m_accuracy;
|
||||||
|
|
||||||
std::list<std::string> m_tags;
|
std::list<std::string> m_tags;
|
||||||
std::vector<actions::Action *> m_tmp_actions;
|
|
||||||
std::list<std::string> m_server_logs;
|
std::list<std::string> m_server_logs;
|
||||||
|
|
||||||
Rule *m_rule;
|
Rule *m_rule;
|
||||||
|
@@ -73,8 +73,10 @@ class Rules;
|
|||||||
class RuleMessage;
|
class RuleMessage;
|
||||||
namespace actions {
|
namespace actions {
|
||||||
class Action;
|
class Action;
|
||||||
|
namespace disruptive {
|
||||||
enum AllowType : int;
|
enum AllowType : int;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
namespace RequestBodyProcessor {
|
namespace RequestBodyProcessor {
|
||||||
class XML;
|
class XML;
|
||||||
class JSON;
|
class JSON;
|
||||||
@@ -339,7 +341,7 @@ class Transaction {
|
|||||||
/**
|
/**
|
||||||
* If allow action was utilized, this variable holds the allow type.
|
* If allow action was utilized, this variable holds the allow type.
|
||||||
*/
|
*/
|
||||||
modsecurity::actions::AllowType m_allowType;
|
modsecurity::actions::disruptive::AllowType m_allowType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds the decode URI. Notice that m_uri holds the raw version
|
* Holds the decode URI. Notice that m_uri holds the raw version
|
||||||
@@ -351,7 +353,8 @@ class Transaction {
|
|||||||
* Actions (disruptive?) that should be taken by the connector related to
|
* Actions (disruptive?) that should be taken by the connector related to
|
||||||
* that transaction.
|
* that transaction.
|
||||||
*/
|
*/
|
||||||
std::vector<actions::Action *> m_actions;
|
std::vector<ModSecurityIntervention> m_actions;
|
||||||
|
ModSecurityIntervention m_it;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds the creation time stamp, using std::time.
|
* Holds the creation time stamp, using std::time.
|
||||||
|
@@ -86,9 +86,7 @@ VARIABLES = \
|
|||||||
ACTIONS = \
|
ACTIONS = \
|
||||||
actions/accuracy.cc \
|
actions/accuracy.cc \
|
||||||
actions/action.cc \
|
actions/action.cc \
|
||||||
actions/allow.cc \
|
|
||||||
actions/audit_log.cc \
|
actions/audit_log.cc \
|
||||||
actions/block.cc \
|
|
||||||
actions/capture.cc \
|
actions/capture.cc \
|
||||||
actions/chain.cc \
|
actions/chain.cc \
|
||||||
actions/ctl/audit_log_parts.cc \
|
actions/ctl/audit_log_parts.cc \
|
||||||
@@ -98,8 +96,12 @@ ACTIONS = \
|
|||||||
actions/ctl/rule_remove_target_by_id.cc \
|
actions/ctl/rule_remove_target_by_id.cc \
|
||||||
actions/ctl/rule_remove_by_id.cc \
|
actions/ctl/rule_remove_by_id.cc \
|
||||||
actions/ctl/request_body_access.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 \
|
||||||
actions/init_col.cc \
|
actions/init_col.cc \
|
||||||
actions/deny.cc \
|
|
||||||
actions/log.cc \
|
actions/log.cc \
|
||||||
actions/log_data.cc \
|
actions/log_data.cc \
|
||||||
actions/maturity.cc \
|
actions/maturity.cc \
|
||||||
@@ -107,16 +109,14 @@ ACTIONS = \
|
|||||||
actions/multi_match.cc \
|
actions/multi_match.cc \
|
||||||
actions/no_audit_log.cc \
|
actions/no_audit_log.cc \
|
||||||
actions/no_log.cc \
|
actions/no_log.cc \
|
||||||
actions/pass.cc \
|
|
||||||
actions/phase.cc \
|
actions/phase.cc \
|
||||||
actions/redirect.cc \
|
|
||||||
actions/rev.cc \
|
actions/rev.cc \
|
||||||
actions/rule_id.cc \
|
actions/rule_id.cc \
|
||||||
actions/severity.cc \
|
actions/severity.cc \
|
||||||
actions/set_sid.cc \
|
actions/set_sid.cc \
|
||||||
actions/set_uid.cc \
|
actions/set_uid.cc \
|
||||||
actions/set_var.cc \
|
actions/set_var.cc \
|
||||||
actions/status.cc \
|
actions/data/status.cc \
|
||||||
actions/skip.cc \
|
actions/skip.cc \
|
||||||
actions/skip_after.cc \
|
actions/skip_after.cc \
|
||||||
actions/tag.cc \
|
actions/tag.cc \
|
||||||
|
@@ -22,16 +22,16 @@
|
|||||||
#include "modsecurity/rule.h"
|
#include "modsecurity/rule.h"
|
||||||
#include "src/utils/string.h"
|
#include "src/utils/string.h"
|
||||||
|
|
||||||
#include "src/actions/block.h"
|
#include "src/actions/disruptive/block.h"
|
||||||
#include "src/actions/chain.h"
|
#include "src/actions/chain.h"
|
||||||
#include "src/actions/deny.h"
|
#include "src/actions/disruptive/deny.h"
|
||||||
#include "src/actions/redirect.h"
|
#include "src/actions/disruptive/redirect.h"
|
||||||
#include "src/actions/status.h"
|
#include "src/actions/data/status.h"
|
||||||
#include "src/actions/rule_id.h"
|
#include "src/actions/rule_id.h"
|
||||||
#include "src/actions/phase.h"
|
#include "src/actions/phase.h"
|
||||||
#include "src/actions/severity.h"
|
#include "src/actions/severity.h"
|
||||||
#include "src/actions/capture.h"
|
#include "src/actions/capture.h"
|
||||||
#include "src/actions/pass.h"
|
#include "src/actions/disruptive/pass.h"
|
||||||
#include "src/actions/log.h"
|
#include "src/actions/log.h"
|
||||||
#include "src/actions/no_log.h"
|
#include "src/actions/no_log.h"
|
||||||
#include "src/actions/multi_match.h"
|
#include "src/actions/multi_match.h"
|
||||||
@@ -55,9 +55,6 @@ bool Action::evaluate(Rule *rule, Transaction *transaction) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Action::fillIntervention(ModSecurityIntervention *i) {
|
|
||||||
}
|
|
||||||
|
|
||||||
Action *Action::instantiate(const std::string& name) {
|
Action *Action::instantiate(const std::string& name) {
|
||||||
std::string status("status:");
|
std::string status("status:");
|
||||||
std::string redirect("redirect:");
|
std::string redirect("redirect:");
|
||||||
@@ -66,13 +63,13 @@ Action *Action::instantiate(const std::string& name) {
|
|||||||
std::string rule_id("id:");
|
std::string rule_id("id:");
|
||||||
|
|
||||||
if (name.compare(0, status.length(), status) == 0) {
|
if (name.compare(0, status.length(), status) == 0) {
|
||||||
return new Status(name);
|
return new data::Status(name);
|
||||||
}
|
}
|
||||||
if (name.compare(0, redirect.length(), redirect) == 0) {
|
if (name.compare(0, redirect.length(), redirect) == 0) {
|
||||||
return new Redirect(name);
|
return new disruptive::Redirect(name);
|
||||||
}
|
}
|
||||||
if (name.compare(0, block.length(), block) == 0) {
|
if (name.compare(0, block.length(), block) == 0) {
|
||||||
return new Block(name);
|
return new disruptive::Block(name);
|
||||||
}
|
}
|
||||||
if (name.compare(0, phase.length(), phase) == 0) {
|
if (name.compare(0, phase.length(), phase) == 0) {
|
||||||
return new Phase(name);
|
return new Phase(name);
|
||||||
@@ -87,10 +84,10 @@ Action *Action::instantiate(const std::string& name) {
|
|||||||
return new Capture(name);
|
return new Capture(name);
|
||||||
}
|
}
|
||||||
if (name == "pass") {
|
if (name == "pass") {
|
||||||
return new Pass(name);
|
return new disruptive::Pass(name);
|
||||||
}
|
}
|
||||||
if (name == "deny") {
|
if (name == "deny") {
|
||||||
return new Deny(name);
|
return new disruptive::Deny(name);
|
||||||
}
|
}
|
||||||
if (name == "log") {
|
if (name == "log") {
|
||||||
return new Log(name);
|
return new Log(name);
|
||||||
|
@@ -13,7 +13,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "src/actions/status.h"
|
#include "src/actions/data/status.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
namespace modsecurity {
|
namespace modsecurity {
|
||||||
namespace actions {
|
namespace actions {
|
||||||
|
namespace data {
|
||||||
|
|
||||||
bool Status::init(std::string *error) {
|
bool Status::init(std::string *error) {
|
||||||
try {
|
try {
|
||||||
@@ -38,16 +38,11 @@ bool Status::init(std::string *error) {
|
|||||||
|
|
||||||
|
|
||||||
bool Status::evaluate(Rule *rule, Transaction *transaction, RuleMessage *rm) {
|
bool Status::evaluate(Rule *rule, Transaction *transaction, RuleMessage *rm) {
|
||||||
rm->m_tmp_actions.push_back(this);
|
transaction->m_it.status = m_status;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Status::fillIntervention(ModSecurityIntervention *i) {
|
} // namespace data
|
||||||
i->status = m_status;
|
|
||||||
i->log = "Status";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace actions
|
} // namespace actions
|
||||||
} // namespace modsecurity
|
} // namespace modsecurity
|
@@ -27,6 +27,8 @@ class Transaction;
|
|||||||
namespace modsecurity {
|
namespace modsecurity {
|
||||||
class Transaction;
|
class Transaction;
|
||||||
namespace actions {
|
namespace actions {
|
||||||
|
namespace data {
|
||||||
|
|
||||||
|
|
||||||
class Status : public Action {
|
class Status : public Action {
|
||||||
public:
|
public:
|
||||||
@@ -36,12 +38,12 @@ class Status : public Action {
|
|||||||
bool init(std::string *error) override;
|
bool init(std::string *error) override;
|
||||||
bool evaluate(Rule *rule, Transaction *transaction, RuleMessage *rm)
|
bool evaluate(Rule *rule, Transaction *transaction, RuleMessage *rm)
|
||||||
override;
|
override;
|
||||||
void fillIntervention(ModSecurityIntervention *i) override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
int m_status;
|
int m_status;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace data
|
||||||
} // namespace actions
|
} // namespace actions
|
||||||
} // namespace modsecurity
|
} // namespace modsecurity
|
||||||
#endif
|
#endif
|
@@ -13,7 +13,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "src/actions/allow.h"
|
#include "src/actions/disruptive/allow.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -26,6 +26,8 @@
|
|||||||
|
|
||||||
namespace modsecurity {
|
namespace modsecurity {
|
||||||
namespace actions {
|
namespace actions {
|
||||||
|
namespace disruptive {
|
||||||
|
|
||||||
|
|
||||||
bool Allow::init(std::string *error) {
|
bool Allow::init(std::string *error) {
|
||||||
std::string a = utils::string::tolower(m_parser_payload);
|
std::string a = utils::string::tolower(m_parser_payload);
|
||||||
@@ -56,5 +58,7 @@ bool Allow::evaluate(Rule *rule, Transaction *transaction) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace disruptive
|
||||||
} // namespace actions
|
} // namespace actions
|
||||||
} // namespace modsecurity
|
} // namespace modsecurity
|
@@ -28,6 +28,8 @@ class Transaction;
|
|||||||
class Rule;
|
class Rule;
|
||||||
|
|
||||||
namespace actions {
|
namespace actions {
|
||||||
|
namespace disruptive {
|
||||||
|
|
||||||
|
|
||||||
enum AllowType : int {
|
enum AllowType : int {
|
||||||
/**
|
/**
|
||||||
@@ -76,6 +78,8 @@ class Allow : public Action {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace disruptive
|
||||||
} // namespace actions
|
} // namespace actions
|
||||||
} // namespace modsecurity
|
} // namespace modsecurity
|
||||||
#endif
|
#endif
|
@@ -13,36 +13,38 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "src/actions/block.h"
|
#include "src/actions/disruptive/block.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "modsecurity/transaction.h"
|
#include "modsecurity/transaction.h"
|
||||||
#include "modsecurity/rule.h"
|
#include "modsecurity/rule.h"
|
||||||
|
#include "modsecurity/rules.h"
|
||||||
#include "modsecurity/intervention.h"
|
#include "modsecurity/intervention.h"
|
||||||
|
#include "src/actions/data/status.h"
|
||||||
|
|
||||||
namespace modsecurity {
|
namespace modsecurity {
|
||||||
namespace actions {
|
namespace actions {
|
||||||
|
namespace disruptive {
|
||||||
|
|
||||||
|
|
||||||
bool Block::evaluate(Rule *rule, Transaction *transaction, RuleMessage *rm) {
|
bool Block::evaluate(Rule *rule, Transaction *transaction, RuleMessage *rm) {
|
||||||
#ifndef NO_LOGS
|
std::string log;
|
||||||
transaction->debug(8, "Running action block");
|
|
||||||
#endif
|
transaction->debug(8, "Marking request as disruptive.");
|
||||||
for (Action *a : rule->m_actionsRuntimePos) {
|
|
||||||
if (a->isDisruptive() == true) {
|
for (Action *a : transaction->m_rules->defaultActions[rule->phase]) {
|
||||||
rm->m_tmp_actions.push_back(a);
|
if (a->isDisruptive() == false) {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
a->evaluate(rule, transaction, rm);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Block::fillIntervention(ModSecurityIntervention *i) {
|
} // namespace disruptive
|
||||||
i->disruptive = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace actions
|
} // namespace actions
|
||||||
} // namespace modsecurity
|
} // namespace modsecurity
|
@@ -28,6 +28,7 @@ namespace modsecurity {
|
|||||||
class Transaction;
|
class Transaction;
|
||||||
|
|
||||||
namespace actions {
|
namespace actions {
|
||||||
|
namespace disruptive {
|
||||||
|
|
||||||
|
|
||||||
class Block : public Action {
|
class Block : public Action {
|
||||||
@@ -36,11 +37,11 @@ class Block : public Action {
|
|||||||
|
|
||||||
bool evaluate(Rule *rule, Transaction *transaction,
|
bool evaluate(Rule *rule, Transaction *transaction,
|
||||||
RuleMessage *rm) override;
|
RuleMessage *rm) override;
|
||||||
void fillIntervention(ModSecurityIntervention *i) override;
|
|
||||||
bool isDisruptive() override { return true; }
|
bool isDisruptive() override { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace disruptive
|
||||||
} // namespace actions
|
} // namespace actions
|
||||||
} // namespace modsecurity
|
} // namespace modsecurity
|
||||||
#endif
|
#endif
|
@@ -13,34 +13,41 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "src/actions/deny.h"
|
#include "src/actions/disruptive/deny.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <cstring>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "modsecurity/transaction.h"
|
#include "modsecurity/transaction.h"
|
||||||
|
|
||||||
namespace modsecurity {
|
namespace modsecurity {
|
||||||
namespace actions {
|
namespace actions {
|
||||||
|
namespace disruptive {
|
||||||
|
|
||||||
|
|
||||||
bool Deny::evaluate(Rule *rule, Transaction *transaction, RuleMessage *rm) {
|
bool Deny::evaluate(Rule *rule, Transaction *transaction, RuleMessage *rm) {
|
||||||
#ifndef NO_LOGS
|
#ifndef NO_LOGS
|
||||||
transaction->debug(8, "Running action deny");
|
transaction->debug(8, "Running action deny");
|
||||||
#endif
|
#endif
|
||||||
rm->m_tmp_actions.push_back(this);
|
std::string log;
|
||||||
|
|
||||||
|
if (transaction->m_it.status == 200) {
|
||||||
|
transaction->m_it.status = 403;
|
||||||
|
}
|
||||||
|
|
||||||
|
log.append("Access denied with code %d");
|
||||||
|
log.append(" (phase ");
|
||||||
|
log.append(std::to_string(rm->m_rule->phase - 1) + "). ");
|
||||||
|
|
||||||
|
transaction->m_it.disruptive = true;
|
||||||
|
transaction->m_it.log = strdup(rm->disruptiveErrorLog(transaction, log).c_str());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Deny::fillIntervention(ModSecurityIntervention *i) {
|
} // namespace disruptive
|
||||||
if (i->status == 200) {
|
|
||||||
i->status = 403;
|
|
||||||
}
|
|
||||||
i->log = "Deny action";
|
|
||||||
i->disruptive = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace actions
|
} // namespace actions
|
||||||
} // namespace modsecurity
|
} // namespace modsecurity
|
@@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
namespace modsecurity {
|
namespace modsecurity {
|
||||||
namespace actions {
|
namespace actions {
|
||||||
|
namespace disruptive {
|
||||||
|
|
||||||
|
|
||||||
class Deny : public Action {
|
class Deny : public Action {
|
||||||
@@ -32,11 +33,11 @@ class Deny : public Action {
|
|||||||
|
|
||||||
bool evaluate(Rule *rule, Transaction *transaction,
|
bool evaluate(Rule *rule, Transaction *transaction,
|
||||||
RuleMessage *rm) override;
|
RuleMessage *rm) override;
|
||||||
void fillIntervention(ModSecurityIntervention *i) override;
|
|
||||||
bool isDisruptive() override { return true; }
|
bool isDisruptive() override { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace disruptive
|
||||||
} // namespace actions
|
} // namespace actions
|
||||||
} // namespace modsecurity
|
} // namespace modsecurity
|
||||||
|
|
@@ -13,7 +13,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "src/actions/pass.h"
|
#include "src/actions/disruptive/pass.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -24,13 +24,22 @@
|
|||||||
|
|
||||||
namespace modsecurity {
|
namespace modsecurity {
|
||||||
namespace actions {
|
namespace actions {
|
||||||
|
namespace disruptive {
|
||||||
|
|
||||||
|
|
||||||
bool Pass::evaluate(Rule *rule, Transaction *transaction, RuleMessage *rm) {
|
bool Pass::evaluate(Rule *rule, Transaction *transaction, RuleMessage *rm) {
|
||||||
rm->m_tmp_actions.clear();
|
transaction->m_it.status = 200;
|
||||||
|
transaction->m_it.disruptive = false;
|
||||||
|
transaction->m_it.url = NULL;
|
||||||
|
transaction->m_it.log = NULL;
|
||||||
|
transaction->m_it.pause = 0;
|
||||||
|
|
||||||
|
transaction->debug(8, "Running action pass");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace disruptive
|
||||||
} // namespace actions
|
} // namespace actions
|
||||||
} // namespace modsecurity
|
} // namespace modsecurity
|
@@ -18,11 +18,12 @@
|
|||||||
#include "modsecurity/actions/action.h"
|
#include "modsecurity/actions/action.h"
|
||||||
#include "modsecurity/transaction.h"
|
#include "modsecurity/transaction.h"
|
||||||
|
|
||||||
#ifndef SRC_ACTIONS_PASS_H_
|
#ifndef SRC_ACTIONS_DISRUPTIVE_PASS_H_
|
||||||
#define SRC_ACTIONS_PASS_H_
|
#define SRC_ACTIONS_DISRUPTIVE_PASS_H_
|
||||||
|
|
||||||
namespace modsecurity {
|
namespace modsecurity {
|
||||||
namespace actions {
|
namespace actions {
|
||||||
|
namespace disruptive {
|
||||||
|
|
||||||
|
|
||||||
class Pass : public Action {
|
class Pass : public Action {
|
||||||
@@ -34,8 +35,10 @@ class Pass : public Action {
|
|||||||
bool isDisruptive() override { return true; }
|
bool isDisruptive() override { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace disruptive
|
||||||
} // namespace actions
|
} // namespace actions
|
||||||
} // namespace modsecurity
|
} // namespace modsecurity
|
||||||
|
|
||||||
|
|
||||||
#endif // SRC_ACTIONS_PASS_H_
|
#endif // SRC_ACTIONS_DISRUPTIVE_PASS_H_
|
@@ -13,16 +13,19 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "src/actions/redirect.h"
|
#include "src/actions/disruptive/redirect.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
#include "modsecurity/transaction.h"
|
#include "modsecurity/transaction.h"
|
||||||
#include "src/macro_expansion.h"
|
#include "src/macro_expansion.h"
|
||||||
|
|
||||||
namespace modsecurity {
|
namespace modsecurity {
|
||||||
namespace actions {
|
namespace actions {
|
||||||
|
namespace disruptive {
|
||||||
|
|
||||||
|
|
||||||
bool Redirect::init(std::string *error) {
|
bool Redirect::init(std::string *error) {
|
||||||
@@ -32,23 +35,26 @@ bool Redirect::init(std::string *error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Redirect::evaluate(Rule *rule, Transaction *transaction) {
|
bool Redirect::evaluate(Rule *rule, Transaction *transaction, RuleMessage *rm) {
|
||||||
m_urlExpanded = MacroExpansion::expand(m_url, transaction);
|
m_urlExpanded = MacroExpansion::expand(m_url, transaction);
|
||||||
transaction->m_actions.push_back(this);
|
std::string log;
|
||||||
|
|
||||||
|
/* if it was changed before, lets keep it. */
|
||||||
|
if (transaction->m_it.status == 200) {
|
||||||
|
transaction->m_it.status = m_status;
|
||||||
|
}
|
||||||
|
log.append("Access denied with code %d");
|
||||||
|
log.append(" (phase ");
|
||||||
|
log.append(std::to_string(rm->m_rule->phase - 1) + "). ");
|
||||||
|
|
||||||
|
transaction->m_it.url = strdup(m_urlExpanded.c_str());
|
||||||
|
transaction->m_it.disruptive = true;
|
||||||
|
transaction->m_it.log = strdup(rm->disruptiveErrorLog(transaction, log).c_str());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Redirect::fillIntervention(ModSecurityIntervention *i) {
|
} // namespace disruptive
|
||||||
/* if it was changed before, lets keep it. */
|
|
||||||
if (i->status == 200) {
|
|
||||||
i->status = m_status;
|
|
||||||
}
|
|
||||||
i->url = m_urlExpanded.c_str();
|
|
||||||
i->log = "Redirecting";
|
|
||||||
i->disruptive = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace actions
|
} // namespace actions
|
||||||
} // namespace modsecurity
|
} // namespace modsecurity
|
@@ -16,6 +16,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "modsecurity/actions/action.h"
|
#include "modsecurity/actions/action.h"
|
||||||
|
#include "modsecurity/rule_message.h"
|
||||||
|
|
||||||
#ifndef SRC_ACTIONS_REDIRECT_H_
|
#ifndef SRC_ACTIONS_REDIRECT_H_
|
||||||
#define SRC_ACTIONS_REDIRECT_H_
|
#define SRC_ACTIONS_REDIRECT_H_
|
||||||
@@ -27,6 +28,8 @@ namespace modsecurity {
|
|||||||
class Transaction;
|
class Transaction;
|
||||||
|
|
||||||
namespace actions {
|
namespace actions {
|
||||||
|
namespace disruptive {
|
||||||
|
|
||||||
|
|
||||||
class Redirect : public Action {
|
class Redirect : public Action {
|
||||||
public:
|
public:
|
||||||
@@ -36,9 +39,8 @@ class Redirect : public Action {
|
|||||||
m_urlExpanded(""),
|
m_urlExpanded(""),
|
||||||
m_url("") { }
|
m_url("") { }
|
||||||
|
|
||||||
bool evaluate(Rule *rule, Transaction *transaction) override;
|
bool evaluate(Rule *rule, Transaction *transaction, RuleMessage *rm) override;
|
||||||
bool init(std::string *error) override;
|
bool init(std::string *error) override;
|
||||||
void fillIntervention(ModSecurityIntervention *i) override;
|
|
||||||
bool isDisruptive() override { return true; }
|
bool isDisruptive() override { return true; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -47,6 +49,8 @@ class Redirect : public Action {
|
|||||||
std::string m_url;
|
std::string m_url;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace disruptive
|
||||||
} // namespace actions
|
} // namespace actions
|
||||||
} // namespace modsecurity
|
} // namespace modsecurity
|
||||||
#endif
|
#endif
|
@@ -48,10 +48,12 @@ namespace actions {
|
|||||||
|
|
||||||
bool Msg::evaluate(Rule *rule, Transaction *transaction, RuleMessage *rm) {
|
bool Msg::evaluate(Rule *rule, Transaction *transaction, RuleMessage *rm) {
|
||||||
std::string msg = data(transaction);
|
std::string msg = data(transaction);
|
||||||
transaction->debug(9, "Saving msg: " + msg);
|
|
||||||
rm->m_message = msg;
|
rm->m_message = msg;
|
||||||
|
transaction->debug(9, "Saving msg: " + msg);
|
||||||
|
|
||||||
transaction->m_collections.storeOrUpdateFirst("RULE:msg", msg);
|
transaction->m_collections.storeOrUpdateFirst("RULE:msg", msg);
|
||||||
|
|
||||||
|
rm->m_server_logs.push_back(rm->errorLog(transaction));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
#include "src/operators/operator.h"
|
#include "src/operators/operator.h"
|
||||||
#include "src/utils/acmp.h"
|
#include "src/utils/acmp.h"
|
||||||
|
#include "src/utils/string.h"
|
||||||
|
|
||||||
namespace modsecurity {
|
namespace modsecurity {
|
||||||
namespace operators {
|
namespace operators {
|
||||||
@@ -78,15 +79,6 @@ void Pm::postOrderTraversal(acmp_btree_node_t *node) {
|
|||||||
node = NULL;
|
node = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pm::replaceAll(std::string str, const std::string& from,
|
|
||||||
const std::string& to) {
|
|
||||||
size_t start_pos = 0;
|
|
||||||
while ((start_pos = str.find(from, start_pos)) != std::string::npos) {
|
|
||||||
size_t end_pos = start_pos + from.length();
|
|
||||||
str.replace(start_pos, end_pos, to);
|
|
||||||
start_pos += to.length();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Pm::evaluate(Transaction *transaction, Rule *rule,
|
bool Pm::evaluate(Transaction *transaction, Rule *rule,
|
||||||
const std::string &input) {
|
const std::string &input) {
|
||||||
@@ -119,8 +111,6 @@ bool Pm::init(const std::string &file, std::string *error) {
|
|||||||
std::istringstream *iss;
|
std::istringstream *iss;
|
||||||
const char *err = NULL;
|
const char *err = NULL;
|
||||||
|
|
||||||
replaceAll(m_param, "\\", "\\\\");
|
|
||||||
|
|
||||||
char *content = parse_pm_content(m_param.c_str(), m_param.length(), &err);
|
char *content = parse_pm_content(m_param.c_str(), m_param.length(), &err);
|
||||||
if (content == NULL) {
|
if (content == NULL) {
|
||||||
iss = new std::istringstream(m_param);
|
iss = new std::istringstream(m_param);
|
||||||
|
@@ -35,8 +35,6 @@ class Pm : public Operator {
|
|||||||
m_p = acmp_create(0);
|
m_p = acmp_create(0);
|
||||||
}
|
}
|
||||||
~Pm();
|
~Pm();
|
||||||
void replaceAll(std::string str, const std::string& from,
|
|
||||||
const std::string& to);
|
|
||||||
bool evaluate(Transaction *transaction, Rule *rule,
|
bool evaluate(Transaction *transaction, Rule *rule,
|
||||||
const std::string &input) override;
|
const std::string &input) override;
|
||||||
bool evaluate(Transaction *transaction,
|
bool evaluate(Transaction *transaction,
|
||||||
|
@@ -22,7 +22,7 @@ class Driver;
|
|||||||
|
|
||||||
#include "src/actions/accuracy.h"
|
#include "src/actions/accuracy.h"
|
||||||
#include "modsecurity/actions/action.h"
|
#include "modsecurity/actions/action.h"
|
||||||
#include "src/actions/allow.h"
|
#include "src/actions/disruptive/allow.h"
|
||||||
#include "src/actions/audit_log.h"
|
#include "src/actions/audit_log.h"
|
||||||
#include "src/actions/ctl/audit_log_parts.h"
|
#include "src/actions/ctl/audit_log_parts.h"
|
||||||
#include "src/actions/ctl/request_body_access.h"
|
#include "src/actions/ctl/request_body_access.h"
|
||||||
@@ -36,7 +36,7 @@ class Driver;
|
|||||||
#include "src/actions/maturity.h"
|
#include "src/actions/maturity.h"
|
||||||
#include "src/actions/msg.h"
|
#include "src/actions/msg.h"
|
||||||
#include "src/actions/phase.h"
|
#include "src/actions/phase.h"
|
||||||
#include "src/actions/redirect.h"
|
#include "src/actions/disruptive/redirect.h"
|
||||||
#include "src/actions/rev.h"
|
#include "src/actions/rev.h"
|
||||||
#include "src/actions/set_sid.h"
|
#include "src/actions/set_sid.h"
|
||||||
#include "src/actions/set_uid.h"
|
#include "src/actions/set_uid.h"
|
||||||
@@ -102,7 +102,7 @@ using modsecurity::Variables::Variations::Exclusion;
|
|||||||
using modsecurity::Variables::XML;
|
using modsecurity::Variables::XML;
|
||||||
using modsecurity::actions::Accuracy;
|
using modsecurity::actions::Accuracy;
|
||||||
using modsecurity::actions::Action;
|
using modsecurity::actions::Action;
|
||||||
using modsecurity::actions::Allow;
|
using modsecurity::actions::disruptive::Allow;
|
||||||
using modsecurity::actions::ctl::AuditLogParts;
|
using modsecurity::actions::ctl::AuditLogParts;
|
||||||
using modsecurity::actions::ctl::RequestBodyProcessorJSON;
|
using modsecurity::actions::ctl::RequestBodyProcessorJSON;
|
||||||
using modsecurity::actions::ctl::RequestBodyProcessorXML;
|
using modsecurity::actions::ctl::RequestBodyProcessorXML;
|
||||||
@@ -111,7 +111,7 @@ using modsecurity::actions::LogData;
|
|||||||
using modsecurity::actions::Maturity;
|
using modsecurity::actions::Maturity;
|
||||||
using modsecurity::actions::Msg;
|
using modsecurity::actions::Msg;
|
||||||
using modsecurity::actions::Phase;
|
using modsecurity::actions::Phase;
|
||||||
using modsecurity::actions::Redirect;
|
using modsecurity::actions::disruptive::Redirect;
|
||||||
using modsecurity::actions::Rev;
|
using modsecurity::actions::Rev;
|
||||||
using modsecurity::actions::SetSID;
|
using modsecurity::actions::SetSID;
|
||||||
using modsecurity::actions::SetUID;
|
using modsecurity::actions::SetUID;
|
||||||
|
49
src/rule.cc
49
src/rule.cc
@@ -251,9 +251,6 @@ void Rule::executeActionsIndependentOfChainedRuleResult(Transaction *trasn,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (auto &z : ruleMessage->m_tmp_actions) {
|
|
||||||
trasn->m_actions.push_back(z);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -505,16 +502,14 @@ void Rule::executeActionsAfterFullMatch(Transaction *trasn,
|
|||||||
a->evaluate(this, trasn, ruleMessage);
|
a->evaluate(this, trasn, ruleMessage);
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
|
trasn->debug(4, "_Not_ running (disruptive) action: "
|
||||||
|
+ a->m_name + ". SecRuleEngine is not On.");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
trasn->debug(4, "Not running disruptive action: " + \
|
trasn->debug(4, "Not running disruptive action: " + \
|
||||||
a->m_name + ". SecRuleEngine is not On");
|
a->m_name + ". SecRuleEngine is not On");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &z : ruleMessage->m_tmp_actions) {
|
|
||||||
trasn->m_actions.push_back(z);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -524,6 +519,8 @@ bool Rule::evaluate(Transaction *trasn) {
|
|||||||
bool recursiveGlobalRet;
|
bool recursiveGlobalRet;
|
||||||
bool containsDisruptive = false;
|
bool containsDisruptive = false;
|
||||||
RuleMessage ruleMessage(this);
|
RuleMessage ruleMessage(this);
|
||||||
|
std::vector<const collection::Variable *> finalVars;
|
||||||
|
std::string eparam;
|
||||||
|
|
||||||
trasn->m_matched.clear();
|
trasn->m_matched.clear();
|
||||||
|
|
||||||
@@ -535,8 +532,7 @@ bool Rule::evaluate(Transaction *trasn) {
|
|||||||
+ ") Executing unconditional rule...");
|
+ ") Executing unconditional rule...");
|
||||||
executeActionsIndependentOfChainedRuleResult(trasn,
|
executeActionsIndependentOfChainedRuleResult(trasn,
|
||||||
&containsDisruptive, &ruleMessage);
|
&containsDisruptive, &ruleMessage);
|
||||||
executeActionsAfterFullMatch(trasn, false, &ruleMessage);
|
goto end_exec;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &i : trasn->m_ruleRemoveById) {
|
for (auto &i : trasn->m_ruleRemoveById) {
|
||||||
@@ -548,7 +544,7 @@ bool Rule::evaluate(Transaction *trasn) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string eparam = MacroExpansion::expand(this->op->m_param, trasn);
|
eparam = MacroExpansion::expand(this->op->m_param, trasn);
|
||||||
|
|
||||||
if (this->op->m_param != eparam) {
|
if (this->op->m_param != eparam) {
|
||||||
eparam = "\"" + eparam + "\" Was: \"" + this->op->m_param + "\"";
|
eparam = "\"" + eparam + "\" Was: \"" + this->op->m_param + "\"";
|
||||||
@@ -565,7 +561,7 @@ bool Rule::evaluate(Transaction *trasn) {
|
|||||||
|
|
||||||
updateRulesVariable(trasn);
|
updateRulesVariable(trasn);
|
||||||
|
|
||||||
std::vector<const collection::Variable *> finalVars = getFinalVars(trasn);
|
finalVars = getFinalVars(trasn);
|
||||||
|
|
||||||
for (const collection::Variable *v : finalVars) {
|
for (const collection::Variable *v : finalVars) {
|
||||||
std::string value = v->m_value;
|
std::string value = v->m_value;
|
||||||
@@ -583,13 +579,6 @@ bool Rule::evaluate(Transaction *trasn) {
|
|||||||
updateMatchedVars(trasn, v->m_key, value);
|
updateMatchedVars(trasn, v->m_key, value);
|
||||||
executeActionsIndependentOfChainedRuleResult(trasn,
|
executeActionsIndependentOfChainedRuleResult(trasn,
|
||||||
&containsDisruptive, &ruleMessage);
|
&containsDisruptive, &ruleMessage);
|
||||||
std::string msg2save = ruleMessage.errorLog(trasn);
|
|
||||||
if (ruleMessage.m_message.empty() == false) {
|
|
||||||
trasn->debug(4,
|
|
||||||
"Scheduled to be saved on the server log: " \
|
|
||||||
+ msg2save + "");
|
|
||||||
ruleMessage.m_server_logs.push_back(msg2save);
|
|
||||||
}
|
|
||||||
globalRet = true;
|
globalRet = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -604,14 +593,7 @@ bool Rule::evaluate(Transaction *trasn) {
|
|||||||
trasn->debug(4, "Rule returned 1.");
|
trasn->debug(4, "Rule returned 1.");
|
||||||
|
|
||||||
if (this->chained == false) {
|
if (this->chained == false) {
|
||||||
executeActionsAfterFullMatch(trasn, containsDisruptive, &ruleMessage);
|
goto end_exec;
|
||||||
trasn->debug(4, "Merging temporary actions to the main transaction.");
|
|
||||||
|
|
||||||
for (const auto &u : ruleMessage.m_server_logs) {
|
|
||||||
trasn->debug(8, "To save: " + u);
|
|
||||||
trasn->serverLog(u);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->chainedRule == NULL) {
|
if (this->chainedRule == NULL) {
|
||||||
@@ -624,15 +606,18 @@ bool Rule::evaluate(Transaction *trasn) {
|
|||||||
recursiveGlobalRet = this->chainedRule->evaluate(trasn);
|
recursiveGlobalRet = this->chainedRule->evaluate(trasn);
|
||||||
|
|
||||||
if (recursiveGlobalRet == true) {
|
if (recursiveGlobalRet == true) {
|
||||||
executeActionsAfterFullMatch(trasn, containsDisruptive, &ruleMessage);
|
goto end_exec;
|
||||||
trasn->debug(4, "Merging temporary actions to the main transaction.");
|
|
||||||
for (const auto &u : ruleMessage.m_server_logs) {
|
|
||||||
trasn->serverLog(u);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
end_exec:
|
||||||
|
executeActionsAfterFullMatch(trasn, containsDisruptive, &ruleMessage);
|
||||||
|
for (const auto &u : ruleMessage.m_server_logs) {
|
||||||
|
trasn->serverLog(u);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -23,6 +23,36 @@
|
|||||||
|
|
||||||
namespace modsecurity {
|
namespace modsecurity {
|
||||||
|
|
||||||
|
std::string RuleMessage::disruptiveErrorLog(Transaction *trans, std::string msg2) {
|
||||||
|
std::string msg;
|
||||||
|
|
||||||
|
msg.append("[client " + std::string(trans->m_clientIpAddress) + "]");
|
||||||
|
msg.append(" ModSecurity: ");
|
||||||
|
msg.append(msg2);
|
||||||
|
msg.append(m_match);
|
||||||
|
msg.append(" [file \"" + std::string(m_ruleFile) + "\"]");
|
||||||
|
msg.append(" [line \"" + std::to_string(m_ruleLine) + "\"]");
|
||||||
|
msg.append(" [id \"" + std::to_string(m_ruleId) + "\"]");
|
||||||
|
msg.append(" [rev \"" + m_rev + "\"]");
|
||||||
|
msg.append(" [msg \"" + m_message + "\"]");
|
||||||
|
msg.append(" [data \"" + m_data + "\"]");
|
||||||
|
msg.append(" [severity \"" +
|
||||||
|
std::to_string(m_severity) + "\"]");
|
||||||
|
msg.append(" [ver \"" + m_ver + "\"]");
|
||||||
|
msg.append(" [maturity \"" + std::to_string(m_maturity) + "\"]");
|
||||||
|
msg.append(" [accuracy \"" + std::to_string(m_accuracy) + "\"]");
|
||||||
|
for (auto &a : m_tags) {
|
||||||
|
msg.append(" [tag \"" + a + "\"]");
|
||||||
|
}
|
||||||
|
msg.append(" [hostname \"" + std::string(trans->m_serverIpAddress) \
|
||||||
|
+ "\"]");
|
||||||
|
msg.append(" [uri \"" + trans->m_uri_no_query_string_decoded + "\"]");
|
||||||
|
msg.append(" [unique_id \"" + trans->m_id + "\"]");
|
||||||
|
|
||||||
|
return modsecurity::utils::string::toHexIfNeeded(msg);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
std::string RuleMessage::errorLog(Transaction *trans) {
|
std::string RuleMessage::errorLog(Transaction *trans) {
|
||||||
std::string msg;
|
std::string msg;
|
||||||
|
|
||||||
|
16
src/rules.cc
16
src/rules.cc
@@ -189,20 +189,20 @@ int Rules::evaluate(int phase, Transaction *transaction) {
|
|||||||
debug(9, "This phase consists of " + std::to_string(rules.size()) + \
|
debug(9, "This phase consists of " + std::to_string(rules.size()) + \
|
||||||
" rule(s).");
|
" rule(s).");
|
||||||
|
|
||||||
if (transaction->m_allowType == actions::FromNowOneAllowType
|
if (transaction->m_allowType == actions::disruptive::FromNowOneAllowType
|
||||||
&& phase != modsecurity::Phases::LoggingPhase) {
|
&& phase != modsecurity::Phases::LoggingPhase) {
|
||||||
debug(9, "Skipping all rules evaluation on this phase as request " \
|
debug(9, "Skipping all rules evaluation on this phase as request " \
|
||||||
"through the utilization of an `allow' action.");
|
"through the utilization of an `allow' action.");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (transaction->m_allowType == actions::RequestAllowType
|
if (transaction->m_allowType == actions::disruptive::RequestAllowType
|
||||||
&& phase <= modsecurity::Phases::RequestBodyPhase) {
|
&& phase <= modsecurity::Phases::RequestBodyPhase) {
|
||||||
debug(9, "Skipping all rules evaluation on this phase as request " \
|
debug(9, "Skipping all rules evaluation on this phase as request " \
|
||||||
"through the utilization of an `allow' action.");
|
"through the utilization of an `allow' action.");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (transaction->m_allowType != actions::NoneAllowType) {
|
if (transaction->m_allowType != actions::disruptive::NoneAllowType) {
|
||||||
transaction->m_allowType = actions::NoneAllowType;
|
transaction->m_allowType = actions::disruptive::NoneAllowType;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < rules.size(); i++) {
|
for (int i = 0; i < rules.size(); i++) {
|
||||||
@@ -223,7 +223,8 @@ int Rules::evaluate(int phase, Transaction *transaction) {
|
|||||||
debug(9, "Skipped rule id '" + std::to_string(rule->rule_id) \
|
debug(9, "Skipped rule id '" + std::to_string(rule->rule_id) \
|
||||||
+ "' due to a `skip' action. Still " + \
|
+ "' due to a `skip' action. Still " + \
|
||||||
std::to_string(transaction->m_skip_next) + " to be skipped.");
|
std::to_string(transaction->m_skip_next) + " to be skipped.");
|
||||||
} else if (transaction->m_allowType != actions::NoneAllowType) {
|
} else if (transaction->m_allowType
|
||||||
|
!= actions::disruptive::NoneAllowType) {
|
||||||
debug(9, "Skipped rule id '" + std::to_string(rule->rule_id) \
|
debug(9, "Skipped rule id '" + std::to_string(rule->rule_id) \
|
||||||
+ "' as request trough the utilization of an `allow' action.");
|
+ "' as request trough the utilization of an `allow' action.");
|
||||||
} else if (m_exceptions.contains(rule->rule_id)) {
|
} else if (m_exceptions.contains(rule->rule_id)) {
|
||||||
@@ -231,6 +232,11 @@ int Rules::evaluate(int phase, Transaction *transaction) {
|
|||||||
+ "'. Removed by an SecRuleRemove directive.");
|
+ "'. Removed by an SecRuleRemove directive.");
|
||||||
} else {
|
} else {
|
||||||
rule->evaluate(transaction);
|
rule->evaluate(transaction);
|
||||||
|
if (transaction->m_it.disruptive == true) {
|
||||||
|
debug(8, "Skipping this phase as this " \
|
||||||
|
"request was already intercepted.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
@@ -33,7 +33,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "modsecurity/actions/action.h"
|
#include "modsecurity/actions/action.h"
|
||||||
#include "src/actions/deny.h"
|
#include "src/actions/disruptive/deny.h"
|
||||||
#include "modsecurity/intervention.h"
|
#include "modsecurity/intervention.h"
|
||||||
#include "modsecurity/modsecurity.h"
|
#include "modsecurity/modsecurity.h"
|
||||||
#include "src/request_body_processor/multipart.h"
|
#include "src/request_body_processor/multipart.h"
|
||||||
@@ -48,7 +48,7 @@
|
|||||||
#include "modsecurity/rule.h"
|
#include "modsecurity/rule.h"
|
||||||
#include "modsecurity/rule_message.h"
|
#include "modsecurity/rule_message.h"
|
||||||
#include "modsecurity/rules_properties.h"
|
#include "modsecurity/rules_properties.h"
|
||||||
#include "src/actions/allow.h"
|
#include "src/actions/disruptive/allow.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -123,7 +123,7 @@ Transaction::Transaction(ModSecurity *ms, Rules *rules, void *logCbData)
|
|||||||
m_responseContentType(NULL),
|
m_responseContentType(NULL),
|
||||||
m_requestBodyAccess(Rules::PropertyNotSetConfigBoolean),
|
m_requestBodyAccess(Rules::PropertyNotSetConfigBoolean),
|
||||||
m_marker(""),
|
m_marker(""),
|
||||||
m_allowType(modsecurity::actions::NoneAllowType),
|
m_allowType(modsecurity::actions::disruptive::NoneAllowType),
|
||||||
m_skip_next(0),
|
m_skip_next(0),
|
||||||
m_creationTimeStamp(utils::cpu_seconds()),
|
m_creationTimeStamp(utils::cpu_seconds()),
|
||||||
m_logCbData(logCbData),
|
m_logCbData(logCbData),
|
||||||
@@ -158,8 +158,14 @@ Transaction::Transaction(ModSecurity *ms, Rules *rules, void *logCbData)
|
|||||||
m_collections.storeOrUpdateFirst("URLENCODED_ERROR", "0");
|
m_collections.storeOrUpdateFirst("URLENCODED_ERROR", "0");
|
||||||
|
|
||||||
#ifndef NO_LOGS
|
#ifndef NO_LOGS
|
||||||
this->debug(4, "Initialising transaction");
|
this->debug(4, "Initializing transaction");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
m_it.status = 200;
|
||||||
|
m_it.disruptive = false;
|
||||||
|
m_it.url = NULL;
|
||||||
|
m_it.log = NULL;
|
||||||
|
m_it.pause = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -879,9 +885,9 @@ int Transaction::appendRequestBody(const unsigned char *buf, size_t len) {
|
|||||||
debug(5, "Request body limit is marked to reject the " \
|
debug(5, "Request body limit is marked to reject the " \
|
||||||
"request");
|
"request");
|
||||||
#endif
|
#endif
|
||||||
Action *a = new actions::Deny("deny");
|
m_it.log = "Request body limit is marked to reject the request";
|
||||||
a->temporaryAction = true;
|
m_it.status = 403;
|
||||||
m_actions.push_back(a);
|
m_it.disruptive = true;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1136,9 +1142,10 @@ int Transaction::appendResponseBody(const unsigned char *buf, size_t len) {
|
|||||||
debug(5, "Response body limit is marked to reject the " \
|
debug(5, "Response body limit is marked to reject the " \
|
||||||
"request");
|
"request");
|
||||||
#endif
|
#endif
|
||||||
Action *a = new actions::Deny("deny");
|
|
||||||
a->temporaryAction = true;
|
m_it.log = "Response body limit is marked to reject the request";
|
||||||
m_actions.push_back(a);
|
m_it.status = 403;
|
||||||
|
m_it.disruptive = true;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1285,20 +1292,26 @@ int Transaction::processLogging() {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
bool Transaction::intervention(ModSecurityIntervention *it) {
|
bool Transaction::intervention(ModSecurityIntervention *it) {
|
||||||
it->status = 200;
|
if (m_it.disruptive) {
|
||||||
it->url = NULL;
|
it->url = m_it.url;
|
||||||
it->disruptive = false;
|
it->disruptive = m_it.disruptive;
|
||||||
if (m_actions.size() > 0) {
|
it->status = m_it.status;
|
||||||
for (Action *a : m_actions) {
|
|
||||||
if (a->action_kind == Action::Kind::RunTimeOnlyIfMatchKind) {
|
if (m_it.log != NULL) {
|
||||||
a->fillIntervention(it);
|
std::string log("");
|
||||||
}
|
const char *log_str;
|
||||||
if (a->temporaryAction) {
|
log.append(m_it.log);
|
||||||
delete a;
|
utils::string::replaceAll(&log, std::string("%d"), std::to_string(it->status));
|
||||||
}
|
log_str = strdup(log.c_str());
|
||||||
|
it->log = log_str;
|
||||||
}
|
}
|
||||||
m_actions.clear();
|
m_it.status = 200;
|
||||||
|
m_it.disruptive = false;
|
||||||
|
m_it.url = NULL;
|
||||||
|
m_it.log = NULL;
|
||||||
|
m_it.pause = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return it->disruptive;
|
return it->disruptive;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -206,6 +206,17 @@ unsigned char *c2x(unsigned what, unsigned char *where) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void replaceAll(std::string *str, const std::string& from,
|
||||||
|
const std::string& to) {
|
||||||
|
size_t start_pos = 0;
|
||||||
|
while ((start_pos = str->find(from, start_pos)) != std::string::npos) {
|
||||||
|
size_t end_pos = start_pos + from.length();
|
||||||
|
str->replace(start_pos, from.length(), to);
|
||||||
|
start_pos += to.length();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace string
|
} // namespace string
|
||||||
} // namespace utils
|
} // namespace utils
|
||||||
} // namespace modsecurity
|
} // namespace modsecurity
|
||||||
|
@@ -66,6 +66,8 @@ std::string tolower(std::string str);
|
|||||||
std::string toupper(std::string str);
|
std::string toupper(std::string str);
|
||||||
std::vector<std::string> split(std::string str, char delimiter);
|
std::vector<std::string> split(std::string str, char delimiter);
|
||||||
void chomp(std::string *str);
|
void chomp(std::string *str);
|
||||||
|
void replaceAll(std::string *str, const std::string& from,
|
||||||
|
const std::string& to);
|
||||||
|
|
||||||
unsigned char x2c(unsigned char *what);
|
unsigned char x2c(unsigned char *what);
|
||||||
unsigned char xsingle2c(unsigned char *what);
|
unsigned char xsingle2c(unsigned char *what);
|
||||||
|
@@ -32,7 +32,7 @@
|
|||||||
"version_min":300000,
|
"version_min":300000,
|
||||||
"title":"Testing Disruptive actions (3/n)",
|
"title":"Testing Disruptive actions (3/n)",
|
||||||
"expected":{
|
"expected":{
|
||||||
"debug_log": "Running action block",
|
"debug_log": "Running .disruptive. action: block",
|
||||||
"http_code":404
|
"http_code":404
|
||||||
},
|
},
|
||||||
"rules":[
|
"rules":[
|
||||||
|
@@ -34,14 +34,14 @@
|
|||||||
"version_min":300000,
|
"version_min":300000,
|
||||||
"title":"Testing Disruptive actions (3/n)",
|
"title":"Testing Disruptive actions (3/n)",
|
||||||
"expected":{
|
"expected":{
|
||||||
"debug_log": "_Not_ running action: deny. Rule _does not_contains a disruptive action, but SecRuleEngine is not On.",
|
"debug_log": "_Not_ running .disruptive. action: block. SecRuleEngine is not On",
|
||||||
"http_code":200
|
"http_code":200
|
||||||
},
|
},
|
||||||
"rules":[
|
"rules":[
|
||||||
"SecRuleEngine On",
|
"SecRuleEngine On",
|
||||||
"SecRuleEngine DetectionOnly",
|
"SecRuleEngine DetectionOnly",
|
||||||
"SecDefaultAction \"phase:2,deny,status:404\"",
|
"SecDefaultAction \"phase:2,deny,status:404\"",
|
||||||
"SecAction \"id:'1',phase:request,nolog,block,t:none\""
|
"SecAction \"id:'1',phase:request,nolog,nolog,block,t:none\""
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user