Computes auditlog during rules load time

This commit is contained in:
Felipe Zimmerle
2020-06-03 20:57:27 -03:00
parent 8aa3e3439d
commit 647717b926
18 changed files with 195 additions and 92 deletions

View File

@@ -15,20 +15,10 @@
#include "src/actions/audit_log.h"
#include <string>
#include "modsecurity/transaction.h"
namespace modsecurity {
namespace actions {
bool AuditLog::execute(Transaction *transaction) noexcept {
transaction->messageSetNoAuditLog(false);
return true;
}
} // namespace actions
} // namespace modsecurity

View File

@@ -16,6 +16,10 @@
#include "src/actions/action_allowed_in_sec_default_action.h"
#include "src/actions/action_type_rule_metadata.h"
#include "src/actions/action_allowed_in_sec_default_action.h"
#ifndef SRC_ACTIONS_AUDIT_LOG_H_
#define SRC_ACTIONS_AUDIT_LOG_H_
@@ -24,13 +28,16 @@ namespace modsecurity {
namespace actions {
class AuditLog : public ActionAllowedAsSecDefaultAction {
class AuditLog : public ActionTypeRuleMetaData,
public ActionAllowedAsSecDefaultAction {
public:
AuditLog()
: Action("auditLog")
{ }
bool execute(Transaction *transaction) noexcept override;
void configure(RuleWithActions *rule) override {
rule->setHasAuditLogAction(true);
}
};

View File

@@ -16,18 +16,10 @@
#include "src/actions/no_audit_log.h"
#include "modsecurity/transaction.h"
namespace modsecurity {
namespace actions {
bool NoAuditLog::execute(Transaction *transaction) noexcept {
transaction->messageSetNoAuditLog(true);
return true;
}
} // namespace actions
} // namespace modsecurity

View File

@@ -15,7 +15,8 @@
#include "modsecurity/actions/action.h"
#include "modsecurity/transaction.h"
#include "src/actions/action_type_rule_metadata.h"
#include "src/actions/action_allowed_in_sec_default_action.h"
@@ -27,13 +28,16 @@ namespace modsecurity {
namespace actions {
class NoAuditLog : public ActionAllowedAsSecDefaultAction {
class NoAuditLog : public ActionTypeRuleMetaData,
public ActionAllowedAsSecDefaultAction {
public:
NoAuditLog()
: Action("noAuditLog")
{ }
bool execute(Transaction *transaction) noexcept override;
void configure(RuleWithActions *rule) override {
rule->setHasNoAuditLogAction(true);
}
};

View File

@@ -266,14 +266,13 @@ bool AuditLog::init(std::string *error) {
}
bool AuditLog::isRelevant(int status) {
bool AuditLog::isRelevant(int status) const noexcept {
std::string sstatus = std::to_string(status);
if (m_relevant.empty()) {
return false;
}
if (sstatus.empty()) {
return true;
}
@@ -283,45 +282,34 @@ bool AuditLog::isRelevant(int status) {
}
bool AuditLog::saveIfRelevant(Transaction *transaction) {
return saveIfRelevant(transaction, -1);
}
bool AuditLog::saveIfRelevant(Transaction *transaction, int parts) {
bool saveAnyway = false;
bool AuditLog::saveIfRelevant(Transaction *transaction) const noexcept {
if (m_status == OffAuditLogStatus || m_status == NotSetLogStatus) {
ms_dbg_a(transaction, 5, "Audit log engine was not set.");
return true;
return false;
}
saveAnyway = transaction->messageSaveAuditLog();
if ((m_status == RelevantOnlyAuditLogStatus
&& this->isRelevant(transaction->m_httpCodeReturned) == false)
&& saveAnyway == false) {
&& isRelevant(transaction->m_httpCodeReturned) == false)) {
ms_dbg_a(transaction, 9, "Return code `" +
std::to_string(transaction->m_httpCodeReturned) + "'" \
" is not interesting to audit logs, relevant code(s): `" +
m_relevant + "'.");
return false;
}
if (parts == -1) {
parts = m_parts;
}
ms_dbg_a(transaction, 5, "Saving this request as part " \
"of the audit logs.");
if (m_writer == NULL) {
ms_dbg_a(transaction, 1, "Internal error, audit log writer is null");
} else {
std::string error;
bool a = m_writer->write(transaction, parts, &error);
if (a == false) {
ms_dbg_a(transaction, 1, "Cannot save the audit log: " + error);
return false;
}
return false;
}
std::string error;
bool a = m_writer->write(transaction, transaction->m_auditLogParts, &error);
if (a == false) {
ms_dbg_a(transaction, 1, "Cannot save the audit log: " + error);
return false;
}
return true;

View File

@@ -157,6 +157,12 @@ int Driver::addSecRule(std::unique_ptr<RuleWithActions> r) {
firstRule->getChainedParent()->setHasLogAction(
firstRule->hasNoLogAction()
);
firstRule->getChainedParent()->setHasAuditLogAction(
firstRule->hasAuditLogAction()
);
firstRule->getChainedParent()->setHasNoAuditLogAction(
firstRule->hasNoAuditLogAction()
);
firstRule = firstRule->getChainedParent();
}
}

View File

@@ -176,6 +176,14 @@ int RuleMessage::getAccuracy() const {
}
bool RuleMessage::toBeAuditLog() const {
if (m_rule) {
return m_rule->isItToBeAuditLogged();
}
return false;
}
std::string RuleMessage::getClientIpAddress() const {
if (m_transaction) {
return *m_transaction->m_clientIpAddress.get();

View File

@@ -90,6 +90,8 @@ RuleWithActions::RuleWithActions(
m_containsCaptureAction(false),
m_containsLogAction(false),
m_containsNoLogAction(false),
m_containsAuditLogAction(false),
m_containsNoAuditLogAction(false),
m_containsMultiMatchAction(false),
m_containsStaticBlockAction(false),
m_defaultSeverity(SEVERITY_NOT_SET),
@@ -100,6 +102,8 @@ RuleWithActions::RuleWithActions(
m_defaultContainsCaptureAction(false),
m_defaultContainsLogAction(false),
m_defaultContainsNoLogAction(false),
m_defaultContainsAuditLogAction(false),
m_defaultContainsNoAuditLogAction(false),
m_defaultContainsMultiMatchAction(false),
m_defaultContainsStaticBlockAction(false),
m_isChained(false) {

View File

@@ -146,6 +146,8 @@ class RuleWithActions : public Rule {
m_containsCaptureAction(r.m_containsCaptureAction),
m_containsLogAction(r.m_containsLogAction),
m_containsNoLogAction(r.m_containsNoLogAction),
m_containsAuditLogAction(r.m_containsAuditLogAction),
m_containsNoAuditLogAction(r.m_containsNoAuditLogAction),
m_containsMultiMatchAction(r.m_containsMultiMatchAction),
m_containsStaticBlockAction(r.m_containsStaticBlockAction),
m_defaultSeverity(r.m_defaultSeverity),
@@ -156,6 +158,8 @@ class RuleWithActions : public Rule {
m_defaultContainsCaptureAction(r.m_defaultContainsCaptureAction),
m_defaultContainsLogAction(r.m_defaultContainsLogAction),
m_defaultContainsNoLogAction(r.m_defaultContainsNoLogAction),
m_defaultContainsAuditLogAction(r.m_defaultContainsAuditLogAction),
m_defaultContainsNoAuditLogAction(r.m_defaultContainsNoAuditLogAction),
m_defaultContainsMultiMatchAction(r.m_defaultContainsMultiMatchAction),
m_defaultContainsStaticBlockAction(r.m_defaultContainsStaticBlockAction),
m_isChained(r.m_isChained) {
@@ -190,6 +194,8 @@ class RuleWithActions : public Rule {
m_containsCaptureAction = r.m_containsCaptureAction;
m_containsLogAction = r.m_containsLogAction;
m_containsNoLogAction = r.m_containsNoLogAction;
m_containsAuditLogAction = r.m_containsAuditLogAction;
m_containsNoAuditLogAction = r.m_containsNoAuditLogAction;
m_containsMultiMatchAction = r.m_containsMultiMatchAction;
m_containsStaticBlockAction = r.m_containsStaticBlockAction;
m_defaultSeverity = r.m_defaultSeverity;
@@ -200,6 +206,8 @@ class RuleWithActions : public Rule {
m_defaultContainsCaptureAction = r.m_defaultContainsCaptureAction;
m_defaultContainsLogAction = r.m_defaultContainsLogAction;
m_defaultContainsNoLogAction = r.m_defaultContainsNoLogAction;
m_defaultContainsAuditLogAction = r.m_defaultContainsAuditLogAction;
m_defaultContainsNoAuditLogAction = r.m_defaultContainsNoAuditLogAction;
m_defaultContainsMultiMatchAction = r.m_defaultContainsMultiMatchAction;
m_defaultContainsStaticBlockAction = r.m_defaultContainsStaticBlockAction;
m_isChained = r.m_isChained;
@@ -358,11 +366,48 @@ class RuleWithActions : public Rule {
inline void setHasMultimatchAction(bool b) { m_containsMultiMatchAction = b; }
inline bool hasMultimatchAction() const { return m_containsMultiMatchAction || m_defaultContainsMultiMatchAction; }
inline bool hasAuditLogAction() const { return m_containsAuditLogAction == true; }
inline void setHasAuditLogAction(bool b) { m_containsAuditLogAction = b; }
inline bool hasNoAuditLogAction() const { return m_containsNoAuditLogAction == true; }
inline void setHasNoAuditLogAction(bool b) { m_containsNoAuditLogAction = b; }
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 isItToBeLogged() const noexcept {
if (m_containsNoLogAction) {
return false;
}
if (m_defaultContainsNoLogAction && !m_containsLogAction) {
return false;
}
return true;
}
inline bool isItToBeAuditLogged() const noexcept {
if (!isItToBeLogged() && !m_containsAuditLogAction
&& !m_defaultContainsAuditLogAction) {
return false;
}
if (m_containsNoAuditLogAction) {
return false;
}
if (m_defaultContainsNoLogAction && !m_containsAuditLogAction) {
return false;
}
return true;
}
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) const;
@@ -543,6 +588,8 @@ class RuleWithActions : public Rule {
bool m_containsCaptureAction:1;
bool m_containsLogAction:1;
bool m_containsNoLogAction:1;
bool m_containsAuditLogAction:1;
bool m_containsNoAuditLogAction:1;
bool m_containsMultiMatchAction:1;
bool m_containsStaticBlockAction:1;
@@ -555,6 +602,8 @@ class RuleWithActions : public Rule {
bool m_defaultContainsCaptureAction:1;
bool m_defaultContainsLogAction:1;
bool m_defaultContainsNoLogAction:1;
bool m_defaultContainsAuditLogAction:1;
bool m_defaultContainsNoAuditLogAction:1;
bool m_defaultContainsMultiMatchAction:1;
bool m_defaultContainsStaticBlockAction:1;

View File

@@ -72,12 +72,15 @@ void TransactionRuleMessageManagement::logMatchLastRuleOnTheChain(RuleWithAction
rm->setRule(rule);
if (rule->hasDisruptiveAction() &&
if (rule->hasDisruptiveAction() && rule->isItToBeLogged() &&
(m_transaction->getRuleEngineState() == RulesSet::DetectionOnlyRuleEngine)) {
/* error */
// The error goes over the disruptive massage. We don't need it here.
//m_transaction->serverLog(rm);
} else if (rule->hasBlockAction() && (!rule->hasNoLogAction()) || rule->hasLogAction()) {
} else if (rule->hasBlockAction() && rule->isItToBeLogged()) {
/* Log as warning. */
m_transaction->serverLog(rm);
} else if (rule->isItToBeLogged()) {
/* Log as warning. */
m_transaction->serverLog(rm);
messageNew();
@@ -88,6 +91,15 @@ void TransactionRuleMessageManagement::messageNew() {
m_rulesMessages.push_back(new RuleMessage(m_transaction));
}
std::list<RuleMessage *> TransactionRuleMessageManagement::messageGetAll() {
std::list<RuleMessage *> messages;
for (RuleMessage *a : m_rulesMessages) {
messages.push_back(a);
}
return messages;
}
/**
* @name Transaction
@@ -272,7 +284,7 @@ Transaction::Transaction(ModSecurity *ms, RulesSet *rules, char *id, void *logCb
ms_dbg(4, "Initializing transaction");
if (m_rules != NULL && m_rules->m_auditLog != NULL) {
m_auditLogParts = this->m_rules->m_auditLog->getParts();
m_auditLogParts = m_rules->m_auditLog->getParts();
}
intervention::clean(&m_it);
@@ -1418,8 +1430,7 @@ int Transaction::processLogging() {
ms_dbg(8, "Checking if this request is suitable to be " \
"saved as an audit log.");
// FIXME: m_auditLogParts can be accessed via Transaction.
bool saved = this->m_rules->m_auditLog->saveIfRelevant(this, m_auditLogParts);
bool saved = m_rules->m_auditLog->saveIfRelevant(this);
if (saved) {
ms_dbg(8, "Request was relevant to be saved. Parts: " +
std::to_string(m_auditLogParts));
@@ -1605,6 +1616,9 @@ std::string Transaction::toOldAuditLogFormat(int parts,
if (parts & audit_log::AuditLog::HAuditLogPart) {
audit_log << "--" << trailer << "-" << "H--" << std::endl;
for (auto a : messageGetAll()) {
if (!a->toBeAuditLog()) {
continue;
}
audit_log << a->log(0, m_httpCodeReturned) << std::endl;
}
audit_log << std::endl;
@@ -1768,6 +1782,10 @@ std::string Transaction::toJSON(int parts) {
strlen("messages"));
yajl_gen_array_open(g);
for (auto a : messageGetAll()) {
if (!a->toBeAuditLog()) {
continue;
}
yajl_gen_map_open(g);
LOGFY_ADD("message", a->m_message.c_str());
yajl_gen_string(g,