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:
Felipe Zimmerle 2020-04-14 11:33:17 -03:00
parent 6c874721cf
commit b079faee97
121 changed files with 5250 additions and 5192 deletions

View File

@ -1,6 +1,10 @@
v3.x.y - YYYY-MMM-DD (to be released)
-------------------------------------
- IMPORTANT: SecDefaultAction behaves changing: SecDefaultAction specified
on a child configuration will overwrite the ones specified on the parent;
Previously it was concatenating.
[@zimmerle]
- Using std::shared_ptr instead of generates its own references counters
for Rules and related.
[@zimmerle]

View File

@ -176,21 +176,22 @@ class ReadingLogsViaRuleMessage {
return;
}
const modsecurity::RuleMessage *ruleMessage = \
reinterpret_cast<const modsecurity::RuleMessage *>(ruleMessagev);
modsecurity::RuleMessage ruleMessage(
*reinterpret_cast<const modsecurity::RuleMessage *>(ruleMessagev));
std::cout << "Rule Id: " << std::to_string(ruleMessage->m_ruleId);
std::cout << " phase: " << std::to_string(ruleMessage->m_phase);
std::cout << "Rule Id: " << std::to_string(ruleMessage.getRuleId());
std::cout << " phase: " << std::to_string(ruleMessage.getPhase());
std::cout << std::endl;
if (ruleMessage->m_isDisruptive) {
if (ruleMessage.isDisruptive()) {
std::cout << " * Disruptive action: ";
std::cout << modsecurity::RuleMessage::log(ruleMessage);
std::cout << modsecurity::RuleMessage::log(&ruleMessage);
std::cout << std::endl;
std::cout << " ** %d is meant to be informed by the webserver.";
std::cout << std::endl;
} else {
std::cout << " * Match, but no disruptive action: ";
std::cout << modsecurity::RuleMessage::log(ruleMessage);
std::cout << modsecurity::RuleMessage::log(&ruleMessage);
std::cout << std::endl;
}
}

View File

@ -69,21 +69,21 @@ static void logCb(void *data, const void *ruleMessagev) {
return;
}
const modsecurity::RuleMessage *ruleMessage = \
reinterpret_cast<const modsecurity::RuleMessage *>(ruleMessagev);
modsecurity::RuleMessage ruleMessage(
*reinterpret_cast<const modsecurity::RuleMessage *>(ruleMessagev));
std::cout << "Rule Id: " << std::to_string(ruleMessage->m_ruleId);
std::cout << " phase: " << std::to_string(ruleMessage->m_phase);
std::cout << "Rule Id: " << std::to_string(ruleMessage.getRuleId());
std::cout << " phase: " << std::to_string(ruleMessage.getPhase());
std::cout << std::endl;
if (ruleMessage->m_isDisruptive) {
if (ruleMessage.isDisruptive()) {
std::cout << " * Disruptive action: ";
std::cout << modsecurity::RuleMessage::log(ruleMessage);
std::cout << modsecurity::RuleMessage::log(&ruleMessage);
std::cout << std::endl;
std::cout << " ** %d is meant to be informed by the webserver.";
std::cout << std::endl;
} else {
std::cout << " * Match, but no disruptive action: ";
std::cout << modsecurity::RuleMessage::log(ruleMessage);
std::cout << modsecurity::RuleMessage::log(&ruleMessage);
std::cout << std::endl;
}
}

View File

@ -78,7 +78,7 @@ class Action {
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; }

View File

@ -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;

View File

@ -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:
@ -88,9 +92,6 @@ class Rule {
virtual bool evaluate(Transaction *transaction) = 0;
virtual bool evaluate(Transaction *transaction,
std::shared_ptr<RuleMessage> rm) = 0;
std::shared_ptr<std::string> getFileName() const {
return m_fileName;
}

View File

@ -55,11 +55,6 @@ class RuleMarker : public Rule {
return *this;
}
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) {

View File

@ -42,120 +42,59 @@ 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),
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(Transaction *transaction) :
m_severity(0),
m_uriNoQueryStringDecoded(trans->m_uri_no_query_string_decoded),
m_ver(rule->m_ver),
m_tags()
m_tags(),
m_data(""),
m_match(""),
m_message(""),
m_reference(""),
m_transaction(transaction),
m_rule(nullptr)
{ }
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),
m_tags(rule->m_tags)
{ }
RuleMessage(const RuleMessage& ruleMessage)
: m_accuracy(ruleMessage.m_accuracy),
m_clientIpAddress(ruleMessage.m_clientIpAddress),
m_data(ruleMessage.m_data),
m_id(ruleMessage.m_id),
m_isDisruptive(ruleMessage.m_isDisruptive),
m_match(ruleMessage.m_match),
m_maturity(ruleMessage.m_maturity),
m_message(ruleMessage.m_message),
m_noAuditLog(ruleMessage.m_noAuditLog),
m_phase(ruleMessage.m_phase),
m_reference(ruleMessage.m_reference),
m_rev(ruleMessage.m_rev),
m_rule(ruleMessage.m_rule),
m_ruleFile(ruleMessage.m_ruleFile),
m_ruleId(ruleMessage.m_ruleId),
m_ruleLine(ruleMessage.m_ruleLine),
m_saveMessage(ruleMessage.m_saveMessage),
m_serverIpAddress(ruleMessage.m_serverIpAddress),
m_severity(ruleMessage.m_severity),
m_uriNoQueryStringDecoded(ruleMessage.m_uriNoQueryStringDecoded),
m_ver(ruleMessage.m_ver),
m_tags(ruleMessage.m_tags)
m_tags(rule->m_tags),
m_data(rule->m_data),
m_match(rule->m_match),
m_message(rule->m_message),
m_reference(rule->m_reference),
m_transaction(rule->m_transaction),
m_rule(rule->m_rule)
{ }
RuleMessage &operator=(const RuleMessage& ruleMessage) {
m_accuracy = ruleMessage.m_accuracy;
m_clientIpAddress = ruleMessage.m_clientIpAddress;
m_data = ruleMessage.m_data;
m_id = ruleMessage.m_id;
m_isDisruptive = ruleMessage.m_isDisruptive;
m_match = ruleMessage.m_match;
m_maturity = ruleMessage.m_maturity;
m_message = ruleMessage.m_message;
m_noAuditLog = ruleMessage.m_noAuditLog;
m_phase = ruleMessage.m_phase;
m_reference = ruleMessage.m_reference;
m_rev = ruleMessage.m_rev;
m_rule = ruleMessage.m_rule;
m_ruleFile = ruleMessage.m_ruleFile;
m_ruleId = ruleMessage.m_ruleId;
m_ruleLine = ruleMessage.m_ruleLine;
m_saveMessage = ruleMessage.m_saveMessage;
m_serverIpAddress = ruleMessage.m_serverIpAddress;
m_severity = ruleMessage.m_severity;
m_uriNoQueryStringDecoded = ruleMessage.m_uriNoQueryStringDecoded;
m_ver = ruleMessage.m_ver;
m_tags = ruleMessage.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;
return *this;
}
void clean() {
m_data = "";
m_match = "";
m_isDisruptive = false;
m_reference = "";
m_severity = 0;
m_ver = "";
}
std::string log() {
@ -183,29 +122,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;
};

View File

@ -55,7 +55,7 @@ class RuleUnconditional : public RuleWithActions {
return *this;
}
virtual bool evaluate(Transaction *transaction, std::shared_ptr<RuleMessage> ruleMessage) override;
virtual bool evaluate(Transaction *transaction) override;
private:
};

View File

@ -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,33 +49,54 @@ class RuleWithActions : public Rule {
~RuleWithActions();
RuleWithActions(const RuleWithActions& r)
RuleWithActions(const RuleWithActions &r)
: Rule(r),
m_rev(r.m_rev),
m_ver(r.m_ver),
m_accuracy(r.m_accuracy),
m_maturity(r.m_maturity),
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_severity(r.m_severity),
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_isChained(r.m_isChained)
{ }
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;
/*
RuleWithActions &operator=(const RuleWithActions& r) {
Rule::operator = (r);
m_rev = r.m_rev;
m_ver = r.m_ver;
//m_rev = r.m_rev;
//m_ver = r.m_ver;
m_accuracy = r.m_accuracy;
m_maturity = r.m_maturity;
m_ruleId = r.m_ruleId;
@ -96,24 +121,21 @@ class RuleWithActions : public Rule {
return *this;
}
virtual bool evaluate(Transaction *transaction, std::shared_ptr<RuleMessage> ruleMessage) override;
//virtual bool evaluate(Transaction *transaction, std::shared_ptr<RuleMessage> ruleMessage) override;
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);
@ -130,34 +152,193 @@ 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;
@ -167,20 +348,82 @@ class RuleWithActions : public Rule {
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;
};

View File

@ -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;
};

View File

@ -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;
};

View File

@ -103,6 +103,7 @@ class ModSecurity;
class Transaction;
class RulesSet;
class RuleMessage;
class RuleWithActions;
namespace actions {
class Action;
namespace disruptive {
@ -319,8 +320,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,
@ -400,7 +449,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;
@ -529,13 +578,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.
*/

View File

@ -40,7 +40,6 @@ bool Accuracy::init(std::string *error) {
bool Accuracy::evaluate(RuleWithActions *rule, Transaction *transaction) {
rule->m_accuracy = m_accuracy;
return true;
}

View File

@ -35,6 +35,7 @@ class Accuracy : public Action {
bool evaluate(RuleWithActions *rule, Transaction *transaction) override;
bool init(std::string *error) override;
int getAccuracy() const { return m_accuracy; }
private:
int m_accuracy;

View File

@ -28,11 +28,8 @@ namespace actions {
bool AuditLog::evaluate(RuleWithActions *rule, Transaction *transaction,
std::shared_ptr<RuleMessage> rm) {
rm->m_noAuditLog = false;
ms_dbg_a(transaction, 9, "Saving transaction to logs");
rm->m_saveMessage = true;
RuleMessage &rm) {
transaction->messageSetNoAuditLog(false);
return true;
}

View File

@ -36,7 +36,7 @@ class AuditLog : public Action {
: Action(action, RunTimeOnlyIfMatchKind) { }
bool evaluate(RuleWithActions *rule, Transaction *transaction,
std::shared_ptr<RuleMessage> rm) override;
RuleMessage &rm) override;
};

View File

@ -30,16 +30,8 @@ namespace actions {
bool Block::evaluate(RuleWithActions *rule, Transaction *transaction,
std::shared_ptr<RuleMessage> rm) {
RuleMessage &rm) {
ms_dbg_a(transaction, 8, "Marking request as disruptive.");
for (auto &a : transaction->m_rules->m_rulesSetPhases[rule->getPhase()]->m_defaultActions) {
if (a->isDisruptive() == false) {
continue;
}
a->evaluate(rule, transaction, rm);
}
return true;
}

View File

@ -36,7 +36,7 @@ class Block : public Action {
explicit Block(const std::string &action) : Action(action) { }
bool evaluate(RuleWithActions *rule, Transaction *transaction,
std::shared_ptr<RuleMessage> rm) override;
RuleMessage &rm) override;
};

View File

@ -26,7 +26,7 @@ namespace actions {
bool Chain::evaluate(RuleWithActions *rule, Transaction *transaction) {
rule->setChained(true);
rule->setHasChainAction(true);
return true;
}

View File

@ -39,7 +39,7 @@ bool Status::init(std::string *error) {
bool Status::evaluate(RuleWithActions *rule, Transaction *transaction,
std::shared_ptr<RuleMessage> rm) {
RuleMessage &rm) {
transaction->m_it.status = m_status;
return true;
}

View File

@ -38,7 +38,7 @@ class Status : public Action {
bool init(std::string *error) override;
bool evaluate(RuleWithActions *rule, Transaction *transaction,
std::shared_ptr<RuleMessage> rm) override;
RuleMessage &rm) override;
int m_status;
};

View File

@ -29,7 +29,7 @@ namespace disruptive {
bool Deny::evaluate(RuleWithActions *rule, Transaction *transaction,
std::shared_ptr<RuleMessage> rm) {
RuleMessage &rm) {
ms_dbg_a(transaction, 8, "Running action deny");
if (transaction->m_it.status == 200) {
@ -38,9 +38,9 @@ bool Deny::evaluate(RuleWithActions *rule, Transaction *transaction,
transaction->m_it.disruptive = true;
intervention::freeLog(&transaction->m_it);
rm->m_isDisruptive = true;
rm.setRule(rule);
transaction->m_it.log = strdup(
rm->log(RuleMessage::LogMessageInfo::ClientLogMessageInfo).c_str());
rm.log(RuleMessage::LogMessageInfo::ClientLogMessageInfo).c_str());
return true;
}

View File

@ -34,7 +34,7 @@ class Deny : public Action {
explicit Deny(const std::string &action) : Action(action) { }
bool evaluate(RuleWithActions *rule, Transaction *transaction,
std::shared_ptr<RuleMessage> rm) override;
RuleMessage &rm) override;
bool isDisruptive() override { return true; }
};

View File

@ -33,7 +33,7 @@ namespace disruptive {
bool Drop::evaluate(RuleWithActions *rule, Transaction *transaction,
std::shared_ptr<RuleMessage> rm) {
RuleMessage &rm) {
ms_dbg_a(transaction, 8, "Running action drop " \
"[executing deny instead of drop.]");
@ -43,9 +43,9 @@ bool Drop::evaluate(RuleWithActions *rule, Transaction *transaction,
transaction->m_it.disruptive = true;
intervention::freeLog(&transaction->m_it);
rm->m_isDisruptive = true;
rm.setRule(rule);
transaction->m_it.log = strdup(
rm->log(RuleMessage::LogMessageInfo::ClientLogMessageInfo).c_str());
rm.log(RuleMessage::LogMessageInfo::ClientLogMessageInfo).c_str());
return true;
}

View File

@ -33,7 +33,7 @@ class Drop : public Action {
explicit Drop(const std::string &action) : Action(action) { }
bool evaluate(RuleWithActions *rule, Transaction *transaction,
std::shared_ptr<RuleMessage> rm) override;
RuleMessage &rm) override;
bool isDisruptive() override { return true; }
};

View File

@ -30,7 +30,7 @@ namespace disruptive {
bool Pass::evaluate(RuleWithActions *rule, Transaction *transaction,
std::shared_ptr<RuleMessage> rm) {
RuleMessage &rm) {
intervention::free(&transaction->m_it);
intervention::reset(&transaction->m_it);

View File

@ -32,7 +32,7 @@ class Pass : public Action {
explicit Pass(const std::string &action) : Action(action) { }
bool evaluate(RuleWithActions *rule, Transaction *transaction,
std::shared_ptr<RuleMessage> rm) override;
RuleMessage &rm) override;
bool isDisruptive() override { return true; }
};

View File

@ -35,7 +35,7 @@ bool Redirect::init(std::string *error) {
bool Redirect::evaluate(RuleWithActions *rule, Transaction *transaction,
std::shared_ptr<RuleMessage> rm) {
RuleMessage &rm) {
std::string m_urlExpanded(m_string->evaluate(transaction));
/* if it was changed before, lets keep it. */
if (transaction->m_it.status == 200
@ -47,9 +47,9 @@ bool Redirect::evaluate(RuleWithActions *rule, Transaction *transaction,
transaction->m_it.url = strdup(m_urlExpanded.c_str());
transaction->m_it.disruptive = true;
intervention::freeLog(&transaction->m_it);
rm->m_isDisruptive = true;
rm.setRule(rule);
transaction->m_it.log = strdup(
rm->log(RuleMessage::LogMessageInfo::ClientLogMessageInfo).c_str());
rm.log(RuleMessage::LogMessageInfo::ClientLogMessageInfo).c_str());
return true;
}

View File

@ -47,7 +47,7 @@ class Redirect : public Action {
m_string(std::move(z)) { }
bool evaluate(RuleWithActions *rule, Transaction *transaction,
std::shared_ptr<RuleMessage> rm) override;
RuleMessage &rm) override;
bool init(std::string *error) override;
bool isDisruptive() override { return true; }

View File

@ -42,7 +42,7 @@ class InitCol : public Action {
bool init(std::string *error) override;
private:
std::string m_collection_key;
std::unique_ptr<RunTimeString> m_string;
std::shared_ptr<RunTimeString> m_string;
};

View File

@ -29,9 +29,7 @@ namespace actions {
bool Log::evaluate(RuleWithActions *rule, Transaction *transaction,
std::shared_ptr<RuleMessage> rm) {
ms_dbg_a(transaction, 9, "Saving transaction to logs");
rm->m_saveMessage = true;
RuleMessage &rm) {
return true;
}

View File

@ -34,7 +34,7 @@ class Log : public Action {
: Action(action, RunTimeOnlyIfMatchKind) { }
bool evaluate(RuleWithActions *rule, Transaction *transaction,
std::shared_ptr<RuleMessage> rm) override;
RuleMessage &rm) override;
};
} // namespace actions

View File

@ -30,8 +30,8 @@ namespace actions {
bool LogData::evaluate(RuleWithActions *rule, Transaction *transaction,
std::shared_ptr<RuleMessage> rm) {
rm->m_data = data(transaction);
RuleMessage &rm) {
rm.m_data = data(transaction);
return true;
}

View File

@ -40,11 +40,11 @@ class LogData : public Action {
m_string(std::move(z)) { }
bool evaluate(RuleWithActions *rule, Transaction *transaction,
std::shared_ptr<RuleMessage> rm) override;
RuleMessage &rm) override;
std::string data(Transaction *Transaction);
std::unique_ptr<RunTimeString> m_string;
std::shared_ptr<RunTimeString> m_string;
};

View File

@ -40,7 +40,6 @@ bool Maturity::init(std::string *error) {
bool Maturity::evaluate(RuleWithActions *rule, Transaction *transaction) {
rule->m_maturity = m_maturity;
return true;
}

View File

@ -35,6 +35,7 @@ class Maturity : public Action {
bool evaluate(RuleWithActions *rule, Transaction *transaction) override;
bool init(std::string *error) override;
int getMaturity() const { return m_maturity; }
private:
int m_maturity;

View File

@ -47,9 +47,9 @@ namespace actions {
bool Msg::evaluate(RuleWithActions *rule, Transaction *transaction,
std::shared_ptr<RuleMessage> rm) {
RuleMessage &rm) {
std::string msg = data(transaction);
rm->m_message = msg;
rm.m_message = msg;
ms_dbg_a(transaction, 9, "Saving msg: " + msg);
return true;

View File

@ -41,10 +41,10 @@ class Msg : public Action {
m_string(std::move(z)) { }
bool evaluate(RuleWithActions *rule, Transaction *transaction,
std::shared_ptr<RuleMessage> rm) override;
RuleMessage &rm) override;
std::string data(Transaction *Transaction);
std::unique_ptr<RunTimeString> m_string;
std::shared_ptr<RunTimeString> m_string;
};

View File

@ -27,10 +27,8 @@ namespace actions {
bool NoAuditLog::evaluate(RuleWithActions *rule, Transaction *transaction,
std::shared_ptr<RuleMessage> rm) {
rm->m_noAuditLog = true;
rm->m_saveMessage = false;
RuleMessage &rm) {
transaction->messageSetNoAuditLog(true);
return true;
}

View File

@ -36,7 +36,7 @@ class NoAuditLog : public Action {
: Action(action, RunTimeOnlyIfMatchKind) { }
bool evaluate(RuleWithActions *rule, Transaction *transaction,
std::shared_ptr<RuleMessage> rm) override;
RuleMessage &rm) override;
};
} // namespace actions

View File

@ -30,8 +30,7 @@ namespace actions {
bool NoLog::evaluate(RuleWithActions *rule, Transaction *transaction,
std::shared_ptr<RuleMessage> rm) {
rm->m_saveMessage = false;
RuleMessage &rm) {
return true;
}

View File

@ -34,7 +34,7 @@ class NoLog : public Action {
: Action(action, RunTimeOnlyIfMatchKind) { }
bool evaluate(RuleWithActions *rule, Transaction *transaction,
std::shared_ptr<RuleMessage> rm) override;
RuleMessage &rm) override;
};
} // namespace actions

View File

@ -34,7 +34,6 @@ bool Rev::init(std::string *error) {
bool Rev::evaluate(RuleWithActions *rule, Transaction *transaction) {
rule->m_rev = m_rev;
return true;
}

View File

@ -33,9 +33,10 @@ class Rev : public Action {
bool evaluate(RuleWithActions *rule, Transaction *transaction) override;
bool init(std::string *error) override;
std::string getRevision() const { return m_rev; }
private:
std::string m_rev;
std::string m_rev;
};

View File

@ -43,7 +43,7 @@ class SetENV : public Action {
bool init(std::string *error) override;
private:
std::unique_ptr<RunTimeString> m_string;
std::shared_ptr<RunTimeString> m_string;
};

View File

@ -43,7 +43,7 @@ class SetRSC : public Action {
bool init(std::string *error) override;
private:
std::unique_ptr<RunTimeString> m_string;
std::shared_ptr<RunTimeString> m_string;
};

View File

@ -43,7 +43,7 @@ class SetSID : public Action {
bool init(std::string *error) override;
private:
std::unique_ptr<RunTimeString> m_string;
std::shared_ptr<RunTimeString> m_string;
};

View File

@ -43,7 +43,7 @@ class SetUID : public Action {
bool init(std::string *error) override;
private:
std::unique_ptr<RunTimeString> m_string;
std::shared_ptr<RunTimeString> m_string;
};

View File

@ -63,8 +63,8 @@ class SetVar : public Action {
private:
SetVarOperation m_operation;
std::unique_ptr<modsecurity::variables::Variable> m_variable;
std::unique_ptr<RunTimeString> m_string;
std::shared_ptr<modsecurity::variables::Variable> m_variable;
std::shared_ptr<RunTimeString> m_string;
};
} // namespace actions

View File

@ -72,17 +72,7 @@ bool Severity::init(std::string *error) {
bool Severity::evaluate(RuleWithActions *rule, Transaction *transaction,
std::shared_ptr<RuleMessage> rm) {
ms_dbg_a(transaction, 9, "This rule severity is: " + \
std::to_string(this->m_severity) + " current transaction is: " + \
std::to_string(transaction->m_highestSeverityAction));
rm->m_severity = m_severity;
if (transaction->m_highestSeverityAction > this->m_severity) {
transaction->m_highestSeverityAction = this->m_severity;
}
RuleMessage &rm) {
return true;
}

View File

@ -36,7 +36,7 @@ class Severity : public Action {
m_severity(0) { }
bool evaluate(RuleWithActions *rule, Transaction *transaction,
std::shared_ptr<RuleMessage> rm) override;
RuleMessage &rm) override;
bool init(std::string *error) override;
int m_severity;

View File

@ -58,11 +58,11 @@ std::string Tag::getName(Transaction *transaction) {
bool Tag::evaluate(RuleWithActions *rule, Transaction *transaction,
std::shared_ptr<RuleMessage> rm) {
RuleMessage &rm) {
std::string tag = getName(transaction);
ms_dbg_a(transaction, 9, "Rule tag: " + tag);
rm->m_tags.push_back(tag);
rm.m_tags.push_back(tag);
return true;
}

View File

@ -39,10 +39,10 @@ class Tag : public Action {
std::string getName(Transaction *transaction);
bool evaluate(RuleWithActions *rule, Transaction *transaction,
std::shared_ptr<RuleMessage> rm) override;
RuleMessage &rm) override;
protected:
std::unique_ptr<RunTimeString> m_string;
std::shared_ptr<RunTimeString> m_string;
};

View File

@ -28,7 +28,6 @@ namespace actions {
bool Ver::evaluate(RuleWithActions *rule, Transaction *transaction) {
rule->m_ver = m_parser_payload;
return true;
}

View File

@ -295,12 +295,7 @@ bool AuditLog::saveIfRelevant(Transaction *transaction, int parts) {
return true;
}
for (RuleMessage &i : transaction->m_rulesMessages) {
if (i.m_noAuditLog == false) {
saveAnyway = true;
break;
}
}
saveAnyway = transaction->messageSaveAuditLog();
if ((m_status == RelevantOnlyAuditLogStatus
&& this->isRelevant(transaction->m_httpCodeReturned) == false)

View File

@ -190,7 +190,7 @@ const std::string& ModSecurity::getConnectorInformation() const {
return m_connector;
}
void ModSecurity::serverLog(void *data, std::shared_ptr<RuleMessage> rm) {
void ModSecurity::serverLog(void *data, RuleMessage *rm) {
if (m_logCb == NULL) {
std::cerr << "Server log callback is not set -- " << rm->errorLog();
std::cerr << std::endl;
@ -209,7 +209,7 @@ void ModSecurity::serverLog(void *data, std::shared_ptr<RuleMessage> rm) {
}
if (m_logProperties & RuleMessageLogProperty) {
const void *a = static_cast<const void *>(rm.get());
const void *a = static_cast<const void *>(rm);
if (m_logProperties & IncludeFullHighlightLogProperty) {
m_logCb(data, a);
return;

View File

@ -25,7 +25,7 @@ namespace operators {
bool BeginsWith::evaluate(Transaction *transaction, RuleWithActions *rule,
const std::string &str, std::shared_ptr<RuleMessage> ruleMessage) {
const std::string &str, RuleMessage *ruleMessage) {
std::string p(m_string->evaluate(transaction));
if (str.size() < p.size()) {

View File

@ -33,7 +33,7 @@ class BeginsWith : public Operator {
: Operator("BeginsWith", std::move(param)) { }
bool evaluate(Transaction *transaction, RuleWithActions *rule, const std::string &str,
std::shared_ptr<RuleMessage> ruleMessage) override;
RuleMessage *ruleMessage) override;
};
} // namespace operators

View File

@ -22,7 +22,7 @@ namespace modsecurity {
namespace operators {
bool Contains::evaluate(Transaction *transaction, RuleWithActions *rule,
const std::string &input, std::shared_ptr<RuleMessage> ruleMessage) {
const std::string &input, RuleMessage *ruleMessage) {
std::string p(m_string->evaluate(transaction));
size_t offset = input.find(p);

View File

@ -36,7 +36,7 @@ class Contains : public Operator {
: Operator("Contains", std::move(param)) { }
bool evaluate(Transaction *transaction, RuleWithActions *rule,
const std::string &str,
std::shared_ptr<RuleMessage> ruleMessage) override;
RuleMessage *ruleMessage) override;
};
} // namespace operators

View File

@ -37,7 +37,7 @@ bool ContainsWord::acceptableChar(const std::string& a, size_t pos) {
}
bool ContainsWord::evaluate(Transaction *transaction, RuleWithActions *rule,
const std::string &str, std::shared_ptr<RuleMessage> ruleMessage) {
const std::string &str, RuleMessage *ruleMessage) {
std::string paramTarget(m_string->evaluate(transaction));
if (paramTarget.empty()) {

View File

@ -34,7 +34,7 @@ class ContainsWord : public Operator {
bool evaluate(Transaction *transaction, RuleWithActions *rule,
const std::string &str,
std::shared_ptr<RuleMessage> ruleMessage) override;
RuleMessage *ruleMessage) override;
private:
static bool acceptableChar(const std::string& a, size_t pos);

View File

@ -26,7 +26,7 @@ namespace operators {
bool DetectSQLi::evaluate(Transaction *t, RuleWithActions *rule,
const std::string& input, std::shared_ptr<RuleMessage> ruleMessage) {
const std::string& input, RuleMessage *ruleMessage) {
char fingerprint[8];
int issqli;

View File

@ -34,7 +34,7 @@ class DetectSQLi : public Operator {
bool evaluate(Transaction *t, RuleWithActions *rule,
const std::string& input,
std::shared_ptr<RuleMessage> ruleMessage) override;
RuleMessage *ruleMessage) override;
};
} // namespace operators

View File

@ -26,7 +26,7 @@ namespace operators {
bool DetectXSS::evaluate(Transaction *t, RuleWithActions *rule,
const std::string& input, std::shared_ptr<RuleMessage> ruleMessage) {
const std::string& input, RuleMessage *ruleMessage) {
int is_xss;
is_xss = libinjection_xss(input.c_str(), input.length());

View File

@ -33,7 +33,7 @@ class DetectXSS : public Operator {
bool evaluate(Transaction *t, RuleWithActions *rule,
const std::string& input,
std::shared_ptr<RuleMessage> ruleMessage) override;
RuleMessage *ruleMessage) override;
};
} // namespace operators

View File

@ -24,7 +24,7 @@ namespace operators {
bool EndsWith::evaluate(Transaction *transaction, RuleWithActions *rule,
const std::string &str, std::shared_ptr<RuleMessage> ruleMessage) {
const std::string &str, RuleMessage *ruleMessage) {
bool ret = false;
std::string p(m_string->evaluate(transaction));

View File

@ -35,7 +35,7 @@ class EndsWith : public Operator {
}
bool evaluate(Transaction *transaction, RuleWithActions *rule,
const std::string &str,
std::shared_ptr<RuleMessage> ruleMessage) override;
RuleMessage *ruleMessage) override;
};

View File

@ -71,7 +71,7 @@ namespace operators {
bool Operator::evaluateInternal(Transaction *transaction,
RuleWithActions *rule, const std::string& a, std::shared_ptr<RuleMessage> rm) {
RuleWithActions *rule, const std::string& a, RuleMessage *rm) {
bool res = evaluate(transaction, rule, a, rm);
if (m_negation) {

View File

@ -114,7 +114,7 @@ class Operator {
bool evaluateInternal(Transaction *t, RuleWithActions *rule,
const std::string& a);
bool evaluateInternal(Transaction *t, RuleWithActions *rule,
const std::string& a, std::shared_ptr<RuleMessage> ruleMessage);
const std::string& a, RuleMessage *ruleMessage);
virtual bool evaluate(Transaction *transaction, const std::string &str);
@ -123,11 +123,11 @@ class Operator {
return evaluate(transaction, str);
}
virtual bool evaluate(Transaction *transaction, RuleWithActions *rule,
const std::string &str, std::shared_ptr<RuleMessage> ruleMessage) {
const std::string &str, RuleMessage *ruleMessage) {
return evaluate(transaction, str);
}
static void logOffset(std::shared_ptr<RuleMessage> ruleMessage, int offset, int len) {
static void logOffset(RuleMessage *ruleMessage, int offset, int len) {
if (ruleMessage) {
ruleMessage->m_reference.append("o"
+ std::to_string(offset) + ","

View File

@ -82,8 +82,8 @@ void Pm::postOrderTraversal(acmp_btree_node_t *node) {
bool Pm::evaluate(Transaction *transaction, RuleWithActions *rule,
const std::string &input, std::shared_ptr<RuleMessage> ruleMessage) {
int rc;
const std::string &input, RuleMessage *ruleMessage) {
int rc = -1;
ACMPT pt;
pt.parser = m_p;
pt.ptr = NULL;

View File

@ -43,7 +43,7 @@ class Pm : public Operator {
~Pm();
bool evaluate(Transaction *transaction, RuleWithActions *rule,
const std::string &str,
std::shared_ptr<RuleMessage> ruleMessage) override;
RuleMessage *ruleMessage) override;
bool init(const std::string &file, std::string *error) override;

View File

@ -202,7 +202,7 @@ void Rbl::furtherInfo(struct sockaddr_in *sin, const std::string &ipStr,
bool Rbl::evaluate(Transaction *t, RuleWithActions *rule,
const std::string& ipStr,
std::shared_ptr<RuleMessage> ruleMessage) {
RuleMessage *ruleMessage) {
struct addrinfo *info = NULL;
std::string host = Rbl::mapIpToAddress(ipStr, t);
int rc = 0;

View File

@ -78,7 +78,7 @@ class Rbl : public Operator {
}
bool evaluate(Transaction *transaction, RuleWithActions *rule,
const std::string& input,
std::shared_ptr<RuleMessage> ruleMessage) override;
RuleMessage *ruleMessage) override;
std::string mapIpToAddress(const std::string &ipStr, Transaction *trans) const;

View File

@ -37,7 +37,7 @@ bool Rx::init(const std::string &arg, std::string *error) {
bool Rx::evaluate(Transaction *transaction, RuleWithActions *rule,
const std::string& input, std::shared_ptr<RuleMessage> ruleMessage) {
const std::string& input, RuleMessage *ruleMessage) {
Regex *re;
if (m_param.empty() && !m_string->m_containsMacro) {

View File

@ -51,7 +51,7 @@ class Rx : public Operator {
bool evaluate(Transaction *transaction, RuleWithActions *rule,
const std::string& input,
std::shared_ptr<RuleMessage> ruleMessage) override;
RuleMessage *ruleMessage) override;
bool init(const std::string &arg, std::string *error) override;

View File

@ -37,7 +37,7 @@ bool RxGlobal::init(const std::string &arg, std::string *error) {
bool RxGlobal::evaluate(Transaction *transaction, RuleWithActions *rule,
const std::string& input, std::shared_ptr<RuleMessage> ruleMessage) {
const std::string& input, RuleMessage *ruleMessage) {
Regex *re;
if (m_param.empty() && !m_string->m_containsMacro) {

View File

@ -51,7 +51,7 @@ class RxGlobal : public Operator {
bool evaluate(Transaction *transaction, RuleWithActions *rule,
const std::string& input,
std::shared_ptr<RuleMessage> ruleMessage) override;
RuleMessage *ruleMessage) override;
bool init(const std::string &arg, std::string *error) override;

View File

@ -111,7 +111,7 @@ bool ValidateByteRange::init(const std::string &file,
bool ValidateByteRange::evaluate(Transaction *transaction, RuleWithActions *rule,
const std::string &input, std::shared_ptr<RuleMessage> ruleMessage) {
const std::string &input, RuleMessage *ruleMessage) {
bool ret = true;
size_t count = 0;

View File

@ -39,7 +39,7 @@ class ValidateByteRange : public Operator {
bool evaluate(Transaction *transaction, RuleWithActions *rule,
const std::string &input,
std::shared_ptr<RuleMessage> ruleMessage) override;
RuleMessage *ruleMessage) override;
bool getRange(const std::string &rangeRepresentation, std::string *error);
bool init(const std::string& file, std::string *error) override;
private:

View File

@ -69,7 +69,7 @@ int ValidateUrlEncoding::validate_url_encoding(const char *input,
bool ValidateUrlEncoding::evaluate(Transaction *transaction, RuleWithActions *rule,
const std::string &input, std::shared_ptr<RuleMessage> ruleMessage) {
const std::string &input, RuleMessage *ruleMessage) {
size_t offset = 0;
bool res = false;

View File

@ -33,7 +33,7 @@ class ValidateUrlEncoding : public Operator {
bool evaluate(Transaction *transaction, RuleWithActions *rule,
const std::string &input,
std::shared_ptr<RuleMessage> ruleMessage) override;
RuleMessage *ruleMessage) override;
static int validate_url_encoding(const char *input, uint64_t input_length,
size_t *offset);

View File

@ -114,7 +114,7 @@ int ValidateUtf8Encoding::detect_utf8_character(
}
bool ValidateUtf8Encoding::evaluate(Transaction *transaction, RuleWithActions *rule,
const std::string &str, std::shared_ptr<RuleMessage> ruleMessage) {
const std::string &str, RuleMessage *ruleMessage) {
unsigned int i, bytes_left;
const char *str_c = str.c_str();

View File

@ -40,7 +40,7 @@ class ValidateUtf8Encoding : public Operator {
bool evaluate(Transaction *transaction, RuleWithActions *rule,
const std::string &str,
std::shared_ptr<RuleMessage> ruleMessage) override;
RuleMessage *ruleMessage) override;
static int detect_utf8_character(const unsigned char *p_read,
unsigned int length);

View File

@ -118,7 +118,7 @@ bool VerifyCC::init(const std::string &param2, std::string *error) {
bool VerifyCC::evaluate(Transaction *t, RuleWithActions *rule,
const std::string& i, std::shared_ptr<RuleMessage> ruleMessage) {
const std::string& i, RuleMessage *ruleMessage) {
int offset = 0;
int target_length = i.length();

View File

@ -37,7 +37,7 @@ class VerifyCC : public Operator {
bool evaluate(Transaction *t, RuleWithActions *rule,
const std::string& input,
std::shared_ptr<RuleMessage> ruleMessage) override;
RuleMessage *ruleMessage) override;
bool init(const std::string &param, std::string *error) override;
private:
pcre *m_pc;

View File

@ -109,7 +109,7 @@ bool VerifyCPF::verify(const char *cpfnumber, int len) {
bool VerifyCPF::evaluate(Transaction *t, RuleWithActions *rule,
const std::string& input, std::shared_ptr<RuleMessage> ruleMessage) {
const std::string& input, RuleMessage *ruleMessage) {
std::list<SMatch> matches;
bool is_cpf = false;
int i;

View File

@ -48,7 +48,7 @@ class VerifyCPF : public Operator {
bool evaluate(Transaction *transaction, RuleWithActions *rule,
const std::string& input,
std::shared_ptr<RuleMessage> ruleMessage) override;
RuleMessage *ruleMessage) override;
bool verify(const char *ssnumber, int len);

View File

@ -111,7 +111,7 @@ invalid:
bool VerifySSN::evaluate(Transaction *t, RuleWithActions *rule,
const std::string& input, std::shared_ptr<RuleMessage> ruleMessage) {
const std::string& input, RuleMessage *ruleMessage) {
std::list<SMatch> matches;
bool is_ssn = false;
int i;

View File

@ -48,7 +48,7 @@ class VerifySSN : public Operator {
bool evaluate(Transaction *transaction, RuleWithActions *rule,
const std::string& input,
std::shared_ptr<RuleMessage> ruleMessage) override;
RuleMessage *ruleMessage) override;

View File

@ -78,7 +78,7 @@ bool VerifySVNR::verify(const char *svnrnumber, int len) {
bool VerifySVNR::evaluate(Transaction *t, RuleWithActions *rule,
const std::string& input, std::shared_ptr<RuleMessage> ruleMessage) {
const std::string& input, RuleMessage* ruleMessage) {
std::list<SMatch> matches;
bool is_svnr = false;
int i;

View File

@ -34,7 +34,7 @@ class VerifySVNR : public Operator {
bool evaluate(Transaction *transaction, RuleWithActions *rule,
const std::string& input,
std::shared_ptr<RuleMessage> ruleMessage) override;
RuleMessage *ruleMessage) override;
bool verify(const char *ssnumber, int len);

View File

@ -25,7 +25,7 @@ namespace operators {
bool Within::evaluate(Transaction *transaction, RuleWithActions *rule,
const std::string &str, std::shared_ptr<RuleMessage> ruleMessage) {
const std::string &str, RuleMessage *ruleMessage) {
bool res = false;
size_t pos = 0;
std::string paramTarget(m_string->evaluate(transaction));

View File

@ -34,7 +34,7 @@ class Within : public Operator {
m_couldContainsMacro = true;
}
bool evaluate(Transaction *transaction, RuleWithActions *rule,
const std::string &str, std::shared_ptr<RuleMessage> ruleMessage) override;
const std::string &str, RuleMessage *ruleMessage) override;
};
} // namespace operators

View File

@ -81,7 +81,7 @@ int Driver::addSecRule(std::unique_ptr<RuleWithActions> r) {
}
/* is it a chained rule? */
if (m_lastRule != nullptr && m_lastRule->isChained()) {
if (m_lastRule != nullptr && m_lastRule->hasChainAction()) {
r->setPhase(m_lastRule->getPhase());
if (r->hasDisruptiveAction()) {
m_parserError << "Disruptive actions can only be specified by";
@ -91,6 +91,74 @@ int Driver::addSecRule(std::unique_ptr<RuleWithActions> r) {
m_lastRule->m_chainedRuleChild = std::move(r);
m_lastRule->m_chainedRuleChild->m_chainedRuleParent = m_lastRule;
m_lastRule = m_lastRule->m_chainedRuleChild.get();
/* Lets set all meta-data to the first rule */
RuleWithActions *firstRule = m_lastRule;
if (!firstRule->hasChainAction()) {
while (firstRule->m_chainedRuleParent != nullptr) {
if (firstRule->hasMessageAction()) {
firstRule->m_chainedRuleParent->setMessageAction(
firstRule->getMessageAction()
);
firstRule->setMessageAction(nullptr);
}
if (firstRule->hasLogDataAction()) {
firstRule->m_chainedRuleParent->setLogDataAction(
firstRule->getLogDataAction()
);
firstRule->setLogDataAction(nullptr);
}
if (firstRule->hasSeverityAction()) {
firstRule->m_chainedRuleParent->setSeverity(
firstRule->getSeverity()
);
}
if (firstRule->hasRevisionAction()) {
firstRule->m_chainedRuleParent->setRevision(
firstRule->getRevision()
);
}
if (firstRule->hasVersionAction()) {
firstRule->m_chainedRuleParent->setVersion(
firstRule->getVersion()
);
}
if (firstRule->hasAccuracyAction()) {
firstRule->m_chainedRuleParent->setAccuracy(
firstRule->getAccuracy()
);
}
if (firstRule->hasMaturityAction()) {
firstRule->m_chainedRuleParent->setMaturity(
firstRule->getMaturity()
);
}
if (firstRule->hasTagAction()) {
firstRule->m_chainedRuleParent->setTags(
firstRule->getTagsAction()
);
firstRule->cleanTags();
}
if (firstRule->hasDisruptiveAction()) {
firstRule->m_chainedRuleParent->setDisruptiveAction(
firstRule->getDisruptiveAction()
);
firstRule->setDisruptiveAction(nullptr);
}
firstRule->m_chainedRuleParent->setHasBlockAction(
firstRule->hasBlockAction()
);
firstRule->m_chainedRuleParent->setHasLogAction(
firstRule->hasLogAction()
);
firstRule->m_chainedRuleParent->setHasLogAction(
firstRule->hasNoLogAction()
);
firstRule = firstRule->m_chainedRuleParent;
}
}
return true;
}
@ -119,6 +187,7 @@ int Driver::addSecRule(std::unique_ptr<RuleWithActions> r) {
}
m_lastRule = rule.get();
m_rulesSetPhases.insert(rule);
return true;

View File

@ -1,4 +1,4 @@
// A Bison parser, made by GNU Bison 3.7.2.
// A Bison parser, made by GNU Bison 3.5.1.
// Locations for Bison parsers in C++
@ -60,13 +60,11 @@ namespace yy {
class position
{
public:
/// Type for file name.
typedef const std::string filename_type;
/// Type for line and column numbers.
typedef int counter_type;
/// Construct a position.
explicit position (filename_type* f = YY_NULLPTR,
explicit position (std::string* f = YY_NULLPTR,
counter_type l = 1,
counter_type c = 1)
: filename (f)
@ -76,7 +74,7 @@ namespace yy {
/// Initialization.
void initialize (filename_type* fn = YY_NULLPTR,
void initialize (std::string* fn = YY_NULLPTR,
counter_type l = 1,
counter_type c = 1)
{
@ -105,7 +103,7 @@ namespace yy {
/** \} */
/// File name to which this position refers.
filename_type* filename;
std::string* filename;
/// Current line number.
counter_type line;
/// Current column number.
@ -148,6 +146,24 @@ namespace yy {
return res -= width;
}
/// Compare two position objects.
inline bool
operator== (const position& pos1, const position& pos2)
{
return (pos1.line == pos2.line
&& pos1.column == pos2.column
&& (pos1.filename == pos2.filename
|| (pos1.filename && pos2.filename
&& *pos1.filename == *pos2.filename)));
}
/// Compare two position objects.
inline bool
operator!= (const position& pos1, const position& pos2)
{
return !(pos1 == pos2);
}
/** \brief Intercept output stream redirection.
** \param ostr the destination output stream
** \param pos a reference to the position to redirect
@ -165,8 +181,6 @@ namespace yy {
class location
{
public:
/// Type for file name.
typedef position::filename_type filename_type;
/// Type for line and column numbers.
typedef position::counter_type counter_type;
@ -183,7 +197,7 @@ namespace yy {
{}
/// Construct a 0-width location in \a f, \a l, \a c.
explicit location (filename_type* f,
explicit location (std::string* f,
counter_type l = 1,
counter_type c = 1)
: begin (f, l, c)
@ -192,7 +206,7 @@ namespace yy {
/// Initialization.
void initialize (filename_type* f = YY_NULLPTR,
void initialize (std::string* f = YY_NULLPTR,
counter_type l = 1,
counter_type c = 1)
{
@ -274,6 +288,20 @@ namespace yy {
return res -= width;
}
/// Compare two location objects.
inline bool
operator== (const location& loc1, const location& loc2)
{
return loc1.begin == loc2.begin && loc1.end == loc2.end;
}
/// Compare two location objects.
inline bool
operator!= (const location& loc1, const location& loc2)
{
return !(loc1 == loc2);
}
/** \brief Intercept output stream redirection.
** \param ostr the destination output stream
** \param loc a reference to the location to redirect
@ -299,6 +327,6 @@ namespace yy {
}
} // yy
#line 303 "location.hh"
#line 331 "location.hh"
#endif // !YY_YY_LOCATION_HH_INCLUDED

View File

@ -1,4 +1,4 @@
// A Bison parser, made by GNU Bison 3.7.2.
// A Bison parser, made by GNU Bison 3.5.1.
// Starting with Bison 3.2, this file is useless: the structure it
// used to define is now defined in "location.hh".

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More