mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-11-15 17:12:14 +03:00
Adds new method for rule merge
IMPORTANT: SecDefaultAction specified on a child configuration will overwrite the ones specified on the parent; Previously it was concatenating.
This commit is contained in:
@@ -56,13 +56,20 @@ class Action {
|
||||
set_name_and_payload(_action);
|
||||
}
|
||||
|
||||
Action(const Action &a)
|
||||
: m_isNone(a.m_isNone),
|
||||
temporaryAction(a.temporaryAction),
|
||||
action_kind(a.action_kind),
|
||||
m_name(a.m_name),
|
||||
m_parser_payload(a.m_parser_payload) { }
|
||||
|
||||
virtual ~Action() { }
|
||||
|
||||
virtual std::string evaluate(const std::string &exp,
|
||||
Transaction *transaction);
|
||||
virtual bool evaluate(RuleWithActions *rule, Transaction *transaction);
|
||||
virtual bool evaluate(RuleWithActions *rule, Transaction *transaction,
|
||||
std::shared_ptr<RuleMessage> ruleMessage) {
|
||||
RuleMessage &ruleMessage) {
|
||||
return evaluate(rule, transaction);
|
||||
}
|
||||
virtual bool init(std::string *error) { return true; }
|
||||
|
||||
@@ -292,7 +292,7 @@ class ModSecurity {
|
||||
*/
|
||||
void setServerLogCb(ModSecLogCb cb, int properties);
|
||||
|
||||
void serverLog(void *data, std::shared_ptr<RuleMessage> rm);
|
||||
void serverLog(void *data, RuleMessage *rm);
|
||||
|
||||
const std::string& getConnectorInformation() const;
|
||||
|
||||
|
||||
@@ -57,13 +57,17 @@ using TransformationResult = std::pair<std::shared_ptr<std::string>,
|
||||
using TransformationResults = std::list<TransformationResult>;
|
||||
|
||||
using Transformation = actions::transformations::Transformation;
|
||||
using Transformations = std::vector<Transformation *>;
|
||||
using Transformations = std::vector<std::shared_ptr<Transformation> >;
|
||||
using TransformationsPtr = std::vector<Transformation *>;
|
||||
|
||||
using Actions = std::vector<actions::Action *>;
|
||||
|
||||
using Tags = std::vector<actions::Tag *>;
|
||||
using SetVars = std::vector<actions::SetVar *>;
|
||||
using MatchActions = std::vector<actions::Action *>;
|
||||
using Tags = std::vector<std::shared_ptr<actions::Tag> >;
|
||||
using TagsPtr = std::vector<actions::Tag *>;
|
||||
using SetVars = std::vector<std::shared_ptr<actions::SetVar> >;
|
||||
using SetVarsPtr = std::vector<actions::SetVar *>;
|
||||
using MatchActions = std::vector<std::shared_ptr<actions::Action > >;
|
||||
using MatchActionsPtr = std::vector<actions::Action *>;
|
||||
|
||||
class Rule {
|
||||
public:
|
||||
@@ -73,10 +77,14 @@ class Rule {
|
||||
m_phase(modsecurity::Phases::RequestHeadersPhase) {
|
||||
}
|
||||
|
||||
virtual bool evaluate(Transaction *transaction) = 0;
|
||||
Rule(const Rule &r)
|
||||
: m_fileName(r.m_fileName),
|
||||
m_lineNumber(r.m_lineNumber),
|
||||
m_phase(r.m_phase) {
|
||||
|
||||
virtual bool evaluate(Transaction *transaction,
|
||||
std::shared_ptr<RuleMessage> rm) = 0;
|
||||
}
|
||||
|
||||
virtual bool evaluate(Transaction *transaction) = 0;
|
||||
|
||||
std::shared_ptr<std::string> getFileName() const {
|
||||
return m_fileName;
|
||||
|
||||
@@ -45,11 +45,6 @@ class RuleMarker : public Rule {
|
||||
m_name(std::make_shared<std::string>(name)) { }
|
||||
|
||||
|
||||
virtual bool evaluate(Transaction *transaction,
|
||||
std::shared_ptr<RuleMessage> rm) override {
|
||||
return evaluate(transaction);
|
||||
}
|
||||
|
||||
virtual bool evaluate(Transaction *transaction) override {
|
||||
if (transaction->isInsideAMarker()) {
|
||||
if (*transaction->getCurrentMarker() == *m_name) {
|
||||
|
||||
@@ -42,67 +42,36 @@ class RuleMessage {
|
||||
ClientLogMessageInfo = 4
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* FIXME: RuleMessage is currently too big, doing a lot of
|
||||
* unnecessary data duplication. Needs to be shrink down.
|
||||
*
|
||||
*/
|
||||
RuleMessage(RuleWithActions *rule, Transaction *trans) :
|
||||
m_accuracy(rule->m_accuracy),
|
||||
m_clientIpAddress(trans->m_clientIpAddress),
|
||||
m_data(""),
|
||||
m_id(trans->m_id),
|
||||
m_isDisruptive(false),
|
||||
m_match(""),
|
||||
m_maturity(rule->m_maturity),
|
||||
m_message(""),
|
||||
m_noAuditLog(false),
|
||||
m_phase(rule->getPhase() - 1),
|
||||
m_reference(""),
|
||||
m_rev(rule->m_rev),
|
||||
m_rule(rule),
|
||||
m_ruleFile(rule->getFileName()),
|
||||
m_ruleId(rule->m_ruleId),
|
||||
m_ruleLine(rule->getLineNumber()),
|
||||
m_saveMessage(true),
|
||||
m_serverIpAddress(trans->m_serverIpAddress),
|
||||
m_severity(0),
|
||||
m_uriNoQueryStringDecoded(trans->m_uri_no_query_string_decoded),
|
||||
m_ver(rule->m_ver)
|
||||
|
||||
explicit RuleMessage(const RuleMessage &ruleMessage) :
|
||||
m_severity(ruleMessage.m_severity),
|
||||
m_tags(),
|
||||
m_data(ruleMessage.m_data),
|
||||
m_match(ruleMessage.m_match),
|
||||
m_message(ruleMessage.m_message),
|
||||
m_reference(ruleMessage.m_reference),
|
||||
m_transaction(ruleMessage.m_transaction),
|
||||
m_rule(ruleMessage.m_rule)
|
||||
{ }
|
||||
|
||||
explicit RuleMessage(RuleMessage *rule) :
|
||||
m_accuracy(rule->m_accuracy),
|
||||
m_clientIpAddress(rule->m_clientIpAddress),
|
||||
m_data(rule->m_data),
|
||||
m_id(rule->m_id),
|
||||
m_isDisruptive(rule->m_isDisruptive),
|
||||
m_match(rule->m_match),
|
||||
m_maturity(rule->m_maturity),
|
||||
m_message(rule->m_message),
|
||||
m_noAuditLog(rule->m_noAuditLog),
|
||||
m_phase(rule->m_phase),
|
||||
m_reference(rule->m_reference),
|
||||
m_rev(rule->m_rev),
|
||||
m_rule(rule->m_rule),
|
||||
m_ruleFile(rule->m_ruleFile),
|
||||
m_ruleId(rule->m_ruleId),
|
||||
m_ruleLine(rule->m_ruleLine),
|
||||
m_saveMessage(rule->m_saveMessage),
|
||||
m_serverIpAddress(rule->m_serverIpAddress),
|
||||
m_severity(rule->m_severity),
|
||||
m_uriNoQueryStringDecoded(rule->m_uriNoQueryStringDecoded),
|
||||
m_ver(rule->m_ver)
|
||||
|
||||
explicit RuleMessage(Transaction *transaction) :
|
||||
m_severity(0),
|
||||
m_tags(),
|
||||
m_data(""),
|
||||
m_match(""),
|
||||
m_message(""),
|
||||
m_reference(""),
|
||||
m_transaction(transaction),
|
||||
m_rule(nullptr)
|
||||
{ }
|
||||
|
||||
|
||||
void clean() {
|
||||
m_data = "";
|
||||
m_match = "";
|
||||
m_isDisruptive = false;
|
||||
m_reference = "";
|
||||
m_severity = 0;
|
||||
m_ver = "";
|
||||
}
|
||||
|
||||
std::string log() {
|
||||
@@ -130,29 +99,122 @@ class RuleMessage {
|
||||
static std::string _details(const RuleMessage *rm);
|
||||
static std::string _errorLogTail(const RuleMessage *rm);
|
||||
|
||||
int m_accuracy;
|
||||
std::shared_ptr<std::string> m_clientIpAddress;
|
||||
std::string m_data;
|
||||
std::shared_ptr<std::string> m_id;
|
||||
bool m_isDisruptive;
|
||||
std::string m_match;
|
||||
int m_maturity;
|
||||
std::string m_message;
|
||||
bool m_noAuditLog;
|
||||
int m_phase;
|
||||
std::string m_reference;
|
||||
std::string m_rev;
|
||||
RuleWithActions *m_rule;
|
||||
std::shared_ptr<std::string> m_ruleFile;
|
||||
int m_ruleId;
|
||||
int m_ruleLine;
|
||||
bool m_saveMessage;
|
||||
std::shared_ptr<std::string> m_serverIpAddress;
|
||||
int m_severity;
|
||||
std::shared_ptr<std::string> m_uriNoQueryStringDecoded;
|
||||
std::string m_ver;
|
||||
RuleWithActions *getRule() const {
|
||||
return m_rule;
|
||||
}
|
||||
|
||||
void setRule(RuleWithActions *rule) {
|
||||
m_rule = rule;
|
||||
}
|
||||
|
||||
bool isSettle() const {
|
||||
return m_rule != nullptr;
|
||||
}
|
||||
|
||||
int getRuleId() const {
|
||||
if (m_rule) {
|
||||
return m_rule->m_ruleId;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int getPhase() const {
|
||||
if (m_rule) {
|
||||
return m_rule->getPhase();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string getFileName() const {
|
||||
if (m_rule) {
|
||||
return *m_rule->getFileName().get();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
int getLineNumber() const {
|
||||
if (m_rule) {
|
||||
return m_rule->getLineNumber();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string getRev() const {
|
||||
if (m_rule) {
|
||||
return m_rule->getRevision();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string getVer() const {
|
||||
if (m_rule) {
|
||||
return m_rule->getRevision();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
int getMaturity() const {
|
||||
if (m_rule) {
|
||||
return m_rule->getMaturity();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int getAccuracy() const {
|
||||
if (m_rule) {
|
||||
return m_rule->getAccuracy();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string getClientIpAddress() const {
|
||||
if (m_transaction) {
|
||||
return *m_transaction->m_clientIpAddress.get();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string getServerIpAddress() const {
|
||||
if (m_transaction) {
|
||||
return *m_transaction->m_serverIpAddress.get();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string getRequestId() const {
|
||||
if (m_transaction) {
|
||||
return *m_transaction->m_id.get();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string getUri() const {
|
||||
if (m_transaction) {
|
||||
return *m_transaction->m_uri_no_query_string_decoded.get();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
bool isDisruptive() const {
|
||||
if (m_rule) {
|
||||
return m_rule->hasDisruptiveAction();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int m_severity;
|
||||
std::list<std::string> m_tags;
|
||||
|
||||
// Transaction
|
||||
std::string m_data;
|
||||
std::string m_match;
|
||||
|
||||
std::string m_message;
|
||||
std::string m_reference;
|
||||
|
||||
private:
|
||||
Transaction *m_transaction;
|
||||
RuleWithActions *m_rule;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -46,7 +46,11 @@ class RuleUnconditional : public RuleWithActions {
|
||||
int lineNumber)
|
||||
: RuleWithActions(actions, transformations, std::move(fileName), lineNumber) { }
|
||||
|
||||
virtual bool evaluate(Transaction *transaction, std::shared_ptr<RuleMessage> ruleMessage) override;
|
||||
RuleUnconditional(const RuleUnconditional &r)
|
||||
: RuleWithActions(r)
|
||||
{ }
|
||||
|
||||
virtual bool evaluate(Transaction *transaction) override;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
@@ -37,6 +37,10 @@ namespace modsecurity {
|
||||
|
||||
class RuleWithActions : public Rule {
|
||||
public:
|
||||
int SEVERITY_NOT_SET = 10;
|
||||
int ACCURACY_NOT_SET = 10;
|
||||
int MATURITY_NOT_SET = 10;
|
||||
|
||||
RuleWithActions(
|
||||
Actions *a,
|
||||
Transformations *t,
|
||||
@@ -45,24 +49,61 @@ class RuleWithActions : public Rule {
|
||||
|
||||
~RuleWithActions();
|
||||
|
||||
virtual bool evaluate(Transaction *transaction, std::shared_ptr<RuleMessage> ruleMessage) override;
|
||||
RuleWithActions(const RuleWithActions &r)
|
||||
: Rule(r),
|
||||
m_ruleId(r.m_ruleId),
|
||||
m_chainedRuleChild(r.m_chainedRuleChild),
|
||||
m_chainedRuleParent(r.m_chainedRuleParent),
|
||||
m_disruptiveAction(r.m_disruptiveAction),
|
||||
m_logData(r.m_logData),
|
||||
m_msg(r.m_msg),
|
||||
m_actionsRuntimePos(r.m_actionsRuntimePos),
|
||||
m_actionsSetVar(r.m_actionsSetVar),
|
||||
m_actionsTag(r.m_actionsTag),
|
||||
m_defaultActionDisruptiveAction(r.m_defaultActionDisruptiveAction),
|
||||
m_defaultActionLogData(r.m_defaultActionLogData),
|
||||
m_defaultActionMsg(r.m_defaultActionMsg),
|
||||
m_defaultActionActionsRuntimePos(r.m_defaultActionActionsRuntimePos),
|
||||
m_defaultActionActionsSetVar(r.m_defaultActionActionsSetVar),
|
||||
m_defaultActionActionsTag(r.m_defaultActionActionsTag),
|
||||
m_transformations(r.m_transformations),
|
||||
m_defaultTransformations(r.m_defaultTransformations),
|
||||
m_severity(r.m_severity),
|
||||
m_revision(r.m_revision),
|
||||
m_version(r.m_version),
|
||||
m_accuracy(r.m_accuracy),
|
||||
m_maturity(r.m_maturity),
|
||||
m_containsCaptureAction(r.m_containsCaptureAction),
|
||||
m_containsLogAction(r.m_containsLogAction),
|
||||
m_containsNoLogAction(r.m_containsNoLogAction),
|
||||
m_containsMultiMatchAction(r.m_containsMultiMatchAction),
|
||||
m_containsStaticBlockAction(r.m_containsStaticBlockAction),
|
||||
m_defaultSeverity(r.m_defaultSeverity),
|
||||
m_defaultRevision(r.m_defaultRevision),
|
||||
m_defaultVersion(r.m_defaultVersion),
|
||||
m_defaultAccuracy(r.m_defaultAccuracy),
|
||||
m_defaultMaturity(r.m_defaultMaturity),
|
||||
m_defaultContainsCaptureAction(r.m_defaultContainsCaptureAction),
|
||||
m_defaultContainsLogAction(r.m_defaultContainsLogAction),
|
||||
m_defaultContainsNoLogAction(r.m_defaultContainsNoLogAction),
|
||||
m_defaultContainsMultiMatchAction(r.m_defaultContainsMultiMatchAction),
|
||||
m_defaultContainsStaticBlockAction(r.m_defaultContainsStaticBlockAction),
|
||||
m_isChained(r.m_isChained) { };
|
||||
|
||||
|
||||
virtual bool evaluate(Transaction *transaction) override;
|
||||
|
||||
|
||||
void executeActionsIndependentOfChainedRuleResult(
|
||||
Transaction *trasn,
|
||||
bool *containsDisruptive,
|
||||
std::shared_ptr<RuleMessage> ruleMessage);
|
||||
bool *containsDisruptive);
|
||||
|
||||
void executeActionsAfterFullMatch(
|
||||
Transaction *trasn,
|
||||
bool containsDisruptive,
|
||||
std::shared_ptr<RuleMessage> ruleMessage);
|
||||
bool containsDisruptive);
|
||||
|
||||
void executeAction(Transaction *trans,
|
||||
bool containsBlock,
|
||||
std::shared_ptr<RuleMessage> ruleMessage,
|
||||
actions::Action *a,
|
||||
bool context);
|
||||
|
||||
@@ -79,57 +120,278 @@ class RuleWithActions : public Rule {
|
||||
int *nth) const;
|
||||
|
||||
|
||||
void performLogging(Transaction *trans,
|
||||
std::shared_ptr<RuleMessage> ruleMessage,
|
||||
bool lastLog = true,
|
||||
bool chainedParentNull = false);
|
||||
void addAction(actions::Action *a);
|
||||
void addTransformation(std::shared_ptr<actions::transformations::Transformation> t) {
|
||||
m_transformations.push_back(t);
|
||||
}
|
||||
void addDefaultAction(std::shared_ptr<actions::Action>);
|
||||
void addDefaultTransformation(std::shared_ptr<actions::transformations::Transformation> t) {
|
||||
m_defaultTransformations.push_back(t);
|
||||
}
|
||||
|
||||
|
||||
std::vector<actions::Action *> getActionsByName(const std::string& name,
|
||||
Transaction *t);
|
||||
bool containsTag(const std::string& name, Transaction *t);
|
||||
bool containsTag(const std::string& name, Transaction *t) const;
|
||||
bool containsMsg(const std::string& name, Transaction *t);
|
||||
|
||||
inline bool isChained() const { return m_isChained == true; }
|
||||
inline bool hasCaptureAction() const { return m_containsCaptureAction == true; }
|
||||
inline void setChained(bool b) { m_isChained = b; }
|
||||
inline bool hasDisruptiveAction() const { return m_disruptiveAction != NULL; }
|
||||
inline bool hasBlockAction() const { return m_containsStaticBlockAction == true; }
|
||||
inline bool hasMultimatch() const { return m_containsMultiMatchAction == true; }
|
||||
|
||||
inline bool hasLogData() const { return m_logData != NULL; }
|
||||
std::string logData(Transaction *t);
|
||||
inline bool hasMsg() const { return m_msg != NULL; }
|
||||
std::string msg(Transaction *t);
|
||||
inline bool hasSeverity() const { return m_severity != NULL; }
|
||||
int severity() const;
|
||||
void clearDefaultActions() {
|
||||
m_defaultSeverity = SEVERITY_NOT_SET;
|
||||
m_defaultRevision = "";
|
||||
m_defaultVersion = "";
|
||||
m_defaultAccuracy = ACCURACY_NOT_SET;
|
||||
m_defaultMaturity = MATURITY_NOT_SET;
|
||||
m_defaultContainsCaptureAction = false;
|
||||
m_defaultContainsLogAction = false;
|
||||
m_defaultContainsNoLogAction = false;
|
||||
m_defaultContainsMultiMatchAction = false;
|
||||
m_defaultContainsStaticBlockAction = false;
|
||||
m_defaultActionLogData = nullptr;
|
||||
m_defaultActionMsg = nullptr;
|
||||
m_defaultActionActionsSetVar.clear();
|
||||
m_defaultActionActionsTag.clear();
|
||||
m_defaultActionActionsRuntimePos.clear();
|
||||
m_defaultActionDisruptiveAction = nullptr;
|
||||
m_defaultActionActionsRuntimePos.clear();
|
||||
m_defaultTransformations.clear();
|
||||
}
|
||||
|
||||
std::string m_rev;
|
||||
std::string m_ver;
|
||||
int m_accuracy;
|
||||
int m_maturity;
|
||||
Transformations getTransformation() const {
|
||||
Transformations dst;
|
||||
for (auto &a : m_defaultTransformations) {
|
||||
dst.push_back(a);
|
||||
}
|
||||
for (auto &a : m_transformations) {
|
||||
dst.push_back(a);
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
TransformationsPtr getTransformationPtr() const {
|
||||
TransformationsPtr dst;
|
||||
for (auto &a : m_defaultTransformations) {
|
||||
dst.push_back(a.get());
|
||||
}
|
||||
for (auto &a : m_transformations) {
|
||||
dst.push_back(a.get());
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
SetVars getSetVarsActions() const {
|
||||
SetVars dst;
|
||||
for (auto &a : m_defaultActionActionsSetVar) {
|
||||
dst.push_back(a);
|
||||
}
|
||||
for (auto &a : m_actionsSetVar) {
|
||||
dst.push_back(a);
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
SetVarsPtr getSetVarsActionsPtr() const {
|
||||
SetVarsPtr dst;
|
||||
for (auto &a : m_defaultActionActionsSetVar) {
|
||||
dst.push_back(a.get());
|
||||
}
|
||||
for (auto &a : m_actionsSetVar) {
|
||||
dst.push_back(a.get());
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
MatchActionsPtr getMatchActionsPtr() const {
|
||||
MatchActionsPtr dst;
|
||||
for (auto &a : m_defaultActionActionsRuntimePos) {
|
||||
dst.push_back(a.get());
|
||||
}
|
||||
for (auto &a : m_actionsRuntimePos) {
|
||||
dst.push_back(a.get());
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
MatchActions getMatchActions() const {
|
||||
MatchActions dst;
|
||||
for (auto &a : m_defaultActionActionsRuntimePos) {
|
||||
dst.push_back(a);
|
||||
}
|
||||
for (auto &a : m_actionsRuntimePos) {
|
||||
dst.push_back(a);
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
inline bool hasChainAction() const { return m_isChained == true; }
|
||||
inline void setHasChainAction(bool b) { m_isChained = b; }
|
||||
inline bool hasChainedParent() const { return m_chainedRuleParent != nullptr; }
|
||||
inline bool hasChainedChild() const { return m_chainedRuleChild.get() != nullptr; }
|
||||
|
||||
inline bool hasCaptureAction() const { return m_containsCaptureAction || m_defaultContainsCaptureAction; }
|
||||
|
||||
inline bool hasDisruptiveAction() const { return m_disruptiveAction != nullptr || m_defaultActionDisruptiveAction != nullptr; }
|
||||
inline void setDisruptiveAction(std::shared_ptr<actions::Action> a) { m_disruptiveAction = a; }
|
||||
inline std::shared_ptr<actions::Action> getDisruptiveAction() const { return m_disruptiveAction; }
|
||||
|
||||
inline bool hasBlockAction() const { return m_containsStaticBlockAction || m_defaultContainsStaticBlockAction; }
|
||||
inline void setHasBlockAction(bool b) { m_containsStaticBlockAction = b; }
|
||||
|
||||
inline bool hasMultimatchAction() const { return m_containsMultiMatchAction || m_defaultContainsMultiMatchAction; }
|
||||
|
||||
inline bool hasLogAction() const { return m_containsLogAction == true; }
|
||||
inline void setHasLogAction(bool b) { m_containsLogAction = b; }
|
||||
inline bool hasNoLogAction() const { return m_containsNoLogAction == true; }
|
||||
inline void setHasNoLogAction(bool b) { m_containsNoLogAction = b; }
|
||||
|
||||
inline bool hasLogDataAction() const { return m_logData != nullptr || m_defaultActionLogData != nullptr; }
|
||||
inline std::shared_ptr<actions::LogData> getLogDataAction() const { return m_logData; }
|
||||
std::string getLogData(/*const */Transaction *t);
|
||||
inline void setLogDataAction(std::shared_ptr<actions::LogData> data) { m_logData = data; }
|
||||
|
||||
inline bool hasMessageAction() const { return m_msg != nullptr || m_defaultActionMsg != nullptr; }
|
||||
inline std::shared_ptr<actions::Msg> getMessageAction() const { return m_msg; }
|
||||
inline void setMessageAction(std::shared_ptr<actions::Msg> msg) { m_msg = msg; }
|
||||
std::string getMessage(/*const */Transaction *t);
|
||||
|
||||
|
||||
inline bool hasSeverityAction() const { return m_severity != SEVERITY_NOT_SET || m_defaultSeverity != SEVERITY_NOT_SET; }
|
||||
inline int getSeverity() const { return (m_severity != SEVERITY_NOT_SET)?m_severity:m_defaultSeverity; }
|
||||
inline void setDefaultActionSeverity(unsigned int severity) { m_defaultSeverity = severity; }
|
||||
inline void setSeverity(unsigned int severity) { m_severity = severity; }
|
||||
|
||||
inline bool hasRevisionAction() const { return m_revision != ""; }
|
||||
inline std::string getRevision() const { return m_revision; };
|
||||
inline void setRevision(const std::string &revision) { m_revision.assign(revision); }
|
||||
|
||||
inline bool hasVersionAction() const { return m_version != ""; }
|
||||
inline std::string getVersion() const { return m_version; };
|
||||
inline void setVersion(const std::string &version) { m_version.assign(version); }
|
||||
|
||||
inline bool hasAccuracyAction() const { return m_accuracy != ACCURACY_NOT_SET || m_defaultAccuracy != ACCURACY_NOT_SET; }
|
||||
inline int getAccuracy() const { return m_accuracy; }
|
||||
inline void setAccuracy(unsigned int accuracy) { m_accuracy = accuracy; }
|
||||
|
||||
inline bool hasMaturityAction() const { return m_maturity != MATURITY_NOT_SET || m_defaultMaturity != MATURITY_NOT_SET; }
|
||||
inline int getMaturity() const { return m_maturity; }
|
||||
inline void setDefaultActionMaturity(unsigned int maturity) { m_defaultMaturity = maturity; }
|
||||
inline void setMaturity(unsigned int maturity) { m_maturity = maturity; }
|
||||
|
||||
inline bool hasTagAction() const { return m_actionsTag.size() > 0; }
|
||||
inline void setTags(Tags tags) {
|
||||
for (auto tag : tags) {
|
||||
m_actionsTag.push_back(tag);
|
||||
}
|
||||
}
|
||||
inline void cleanTags() {
|
||||
m_actionsTag.clear();
|
||||
}
|
||||
Tags getTagsAction() const {
|
||||
Tags dst;
|
||||
for (auto &a : m_defaultActionActionsTag) {
|
||||
dst.push_back(a);
|
||||
}
|
||||
for (auto &a : m_actionsTag) {
|
||||
dst.push_back(a);
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
TagsPtr getTagsActionPtr() const {
|
||||
TagsPtr dst;
|
||||
for (auto &a : m_defaultActionActionsTag) {
|
||||
dst.push_back(a.get());
|
||||
}
|
||||
for (auto &a : m_actionsTag) {
|
||||
dst.push_back(a.get());
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
|
||||
int64_t m_ruleId;
|
||||
|
||||
std::unique_ptr<RuleWithActions> m_chainedRuleChild;
|
||||
std::shared_ptr<RuleWithActions> m_chainedRuleChild;
|
||||
RuleWithActions *m_chainedRuleParent;
|
||||
|
||||
private:
|
||||
/* actions */
|
||||
actions::Action *m_disruptiveAction;
|
||||
actions::LogData *m_logData;
|
||||
actions::Msg *m_msg;
|
||||
actions::Severity *m_severity;
|
||||
std::shared_ptr<actions::Action> m_disruptiveAction;
|
||||
std::shared_ptr<actions::LogData> m_logData;
|
||||
std::shared_ptr<actions::Msg> m_msg;
|
||||
MatchActions m_actionsRuntimePos;
|
||||
SetVars m_actionsSetVar;
|
||||
Tags m_actionsTag;
|
||||
|
||||
/* actions || SecDefaultAction */
|
||||
std::shared_ptr<actions::Action> m_defaultActionDisruptiveAction;
|
||||
std::shared_ptr<actions::LogData> m_defaultActionLogData;
|
||||
std::shared_ptr<actions::Msg> m_defaultActionMsg;
|
||||
MatchActions m_defaultActionActionsRuntimePos;
|
||||
SetVars m_defaultActionActionsSetVar;
|
||||
Tags m_defaultActionActionsTag;
|
||||
|
||||
/* actions > transformations */
|
||||
Transformations m_transformations;
|
||||
|
||||
/* actions > transformations || SecDefaultAction */
|
||||
Transformations m_defaultTransformations;
|
||||
|
||||
|
||||
/* || */
|
||||
/**
|
||||
* 0 - EMERGENCY: is generated from correlation of anomaly
|
||||
* scoring data where there is an inbound
|
||||
* attack and an outbound leakage.
|
||||
* 1 - ALERT: is generated from correlation where there is
|
||||
* an inbound attack and an outbound application
|
||||
* level error.
|
||||
* 2 - CRITICAL: Anomaly Score of 5. Is the highest severity
|
||||
* level possible without correlation. It is
|
||||
* normally generated by the web attack rules
|
||||
* (40 level files).
|
||||
* 3 - ERROR: Error - Anomaly Score of 4. Is generated mostly
|
||||
* from outbound leakage rules (50 level files).
|
||||
* 4 - WARNING: Anomaly Score of 3. Is generated by malicious
|
||||
* client rules (35 level files).
|
||||
* 5 - NOTICE: Anomaly Score of 2. Is generated by the Protocol
|
||||
* policy and anomaly files.
|
||||
* 6 - INFO
|
||||
* 7 - DEBUG
|
||||
**/
|
||||
unsigned int m_severity:3;
|
||||
|
||||
std::string m_revision;
|
||||
std::string m_version;
|
||||
|
||||
/**
|
||||
* 1-9 where 9 is very strong and 1 has many false positives
|
||||
*/
|
||||
unsigned int m_accuracy:3;
|
||||
/**
|
||||
* 1-9 where 9 is extensively tested and 1 is a brand new experimental rule
|
||||
*/
|
||||
unsigned int m_maturity:3;
|
||||
|
||||
|
||||
bool m_containsCaptureAction:1;
|
||||
bool m_containsLogAction:1;
|
||||
bool m_containsNoLogAction:1;
|
||||
bool m_containsMultiMatchAction:1;
|
||||
bool m_containsStaticBlockAction:1;
|
||||
|
||||
/* || SecDefaultAction */
|
||||
unsigned int m_defaultSeverity:3;
|
||||
std::string m_defaultRevision;
|
||||
std::string m_defaultVersion;
|
||||
unsigned int m_defaultAccuracy:3;
|
||||
unsigned int m_defaultMaturity:3;
|
||||
bool m_defaultContainsCaptureAction:1;
|
||||
bool m_defaultContainsLogAction:1;
|
||||
bool m_defaultContainsNoLogAction:1;
|
||||
bool m_defaultContainsMultiMatchAction:1;
|
||||
bool m_defaultContainsStaticBlockAction:1;
|
||||
|
||||
bool m_isChained:1;
|
||||
};
|
||||
|
||||
|
||||
@@ -45,10 +45,14 @@ class RuleWithOperator : public RuleWithActions {
|
||||
std::unique_ptr<std::string> fileName,
|
||||
int lineNumber);
|
||||
|
||||
RuleWithOperator(const RuleWithOperator &op)
|
||||
: RuleWithActions(op),
|
||||
m_variables(op.m_variables),
|
||||
m_operator(op.m_operator) { };
|
||||
|
||||
virtual ~RuleWithOperator();
|
||||
|
||||
bool evaluate(Transaction *transaction,
|
||||
std::shared_ptr<RuleMessage> rm) override;
|
||||
bool evaluate(Transaction *transaction) override;
|
||||
|
||||
void getVariablesExceptions(Transaction *t,
|
||||
variables::Variables *exclusion, variables::Variables *addition);
|
||||
@@ -56,7 +60,7 @@ class RuleWithOperator : public RuleWithActions {
|
||||
variables::Variables *eclusion, Transaction *trans);
|
||||
|
||||
bool executeOperatorAt(Transaction *trasn, const std::string &key,
|
||||
std::string value, std::shared_ptr<RuleMessage> rm);
|
||||
std::string value);
|
||||
|
||||
static void updateMatchedVars(Transaction *trasn, const std::string &key,
|
||||
const std::string &value);
|
||||
@@ -70,8 +74,8 @@ class RuleWithOperator : public RuleWithActions {
|
||||
}
|
||||
|
||||
private:
|
||||
modsecurity::variables::Variables *m_variables;
|
||||
operators::Operator *m_operator;
|
||||
std::shared_ptr<modsecurity::variables::Variables> m_variables;
|
||||
std::shared_ptr<operators::Operator> m_operator;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -80,11 +80,14 @@ class Rules {
|
||||
return true;
|
||||
}
|
||||
|
||||
void fixDefaultActions();
|
||||
|
||||
size_t size() const { return m_rules.size(); }
|
||||
std::shared_ptr<Rule> operator[](int index) const { return m_rules[index]; }
|
||||
std::shared_ptr<Rule> at(int index) const { return m_rules[index]; }
|
||||
|
||||
std::vector<std::shared_ptr<actions::Action> > m_defaultActions;
|
||||
std::vector<std::shared_ptr<actions::transformations::Transformation> > m_defaultTransformations;
|
||||
|
||||
std::vector<std::shared_ptr<Rule> > m_rules;
|
||||
};
|
||||
|
||||
@@ -102,6 +102,7 @@ class ModSecurity;
|
||||
class Transaction;
|
||||
class RulesSet;
|
||||
class RuleMessage;
|
||||
class RuleWithActions;
|
||||
namespace actions {
|
||||
class Action;
|
||||
namespace disruptive {
|
||||
@@ -317,8 +318,56 @@ class TransactionSecMarkerManagement {
|
||||
std::shared_ptr<std::string> m_marker;
|
||||
};
|
||||
|
||||
class TransactionRuleMessageManagement {
|
||||
public:
|
||||
explicit TransactionRuleMessageManagement(Transaction *t)
|
||||
: m_transaction(t),
|
||||
m_noAuditLog(false) {
|
||||
messageNew();
|
||||
};
|
||||
|
||||
RuleMessage *messageGetLast();
|
||||
void messageNew();
|
||||
|
||||
void logMatchLastRuleOnTheChain(RuleWithActions *rule);
|
||||
|
||||
void messageSetNoAuditLog(bool a) {
|
||||
m_noAuditLog = a;
|
||||
}
|
||||
|
||||
bool messageSaveAuditLog() const {
|
||||
return m_noAuditLog;
|
||||
}
|
||||
|
||||
std::list<RuleMessage *> messageGetAll() {
|
||||
std::list<RuleMessage *> messages;
|
||||
for (RuleMessage *a : m_rulesMessages) {
|
||||
messages.push_back(a);
|
||||
}
|
||||
|
||||
return messages;
|
||||
}
|
||||
|
||||
void messageClear() {
|
||||
m_rulesMessages.clear();
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* This variable holds all the messages asked to be save by the utilization
|
||||
* of the actions: `log_data' and `msg'. These should be included on the
|
||||
* auditlogs.
|
||||
*/
|
||||
std::list<RuleMessage *> m_rulesMessages;
|
||||
|
||||
Transaction *m_transaction;
|
||||
bool m_noAuditLog;
|
||||
};
|
||||
|
||||
|
||||
/** @ingroup ModSecurity_CPP_API */
|
||||
class Transaction : public TransactionAnchoredVariables, public TransactionSecMarkerManagement {
|
||||
class Transaction : public TransactionAnchoredVariables, public TransactionSecMarkerManagement, \
|
||||
public TransactionRuleMessageManagement {
|
||||
public:
|
||||
Transaction(ModSecurity *transaction, RulesSet *rules, void *logCbData);
|
||||
Transaction(ModSecurity *transaction, RulesSet *rules, char *id,
|
||||
@@ -398,7 +447,7 @@ class Transaction : public TransactionAnchoredVariables, public TransactionSecMa
|
||||
#ifndef NO_LOGS
|
||||
void debug(int, std::string) const;
|
||||
#endif
|
||||
void serverLog(std::shared_ptr<RuleMessage> rm);
|
||||
void serverLog(RuleMessage *rm);
|
||||
|
||||
int getRuleEngineState() const;
|
||||
|
||||
@@ -527,13 +576,6 @@ class Transaction : public TransactionAnchoredVariables, public TransactionSecMa
|
||||
*/
|
||||
std::list< std::pair<int, std::string> > m_auditLogModifier;
|
||||
|
||||
/**
|
||||
* This variable holds all the messages asked to be save by the utilization
|
||||
* of the actions: `log_data' and `msg'. These should be included on the
|
||||
* auditlogs.
|
||||
*/
|
||||
std::list<modsecurity::RuleMessage> m_rulesMessages;
|
||||
|
||||
/**
|
||||
* Holds the request body, in case of any.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user