mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-13 13:26:01 +03:00
Add ctl:auditengine action support
This commit is contained in:
parent
cb80837e6a
commit
2d51efae49
@ -96,6 +96,7 @@ TESTS+=test/test-cases/regression/action-ctl_request_body_access.json
|
||||
TESTS+=test/test-cases/regression/action-ctl_request_body_processor.json
|
||||
TESTS+=test/test-cases/regression/action-ctl_request_body_processor_urlencoded.json
|
||||
TESTS+=test/test-cases/regression/action-ctl_rule_engine.json
|
||||
TESTS+=test/test-cases/regression/action-ctl_audit_engine.json
|
||||
TESTS+=test/test-cases/regression/action-ctl_rule_remove_by_id.json
|
||||
TESTS+=test/test-cases/regression/action-ctl_rule_remove_by_tag.json
|
||||
TESTS+=test/test-cases/regression/action-ctl_rule_remove_target_by_id.json
|
||||
|
@ -22,12 +22,11 @@
|
||||
#ifndef HEADERS_MODSECURITY_AUDIT_LOG_H_
|
||||
#define HEADERS_MODSECURITY_AUDIT_LOG_H_
|
||||
|
||||
#include "modsecurity/transaction.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
namespace modsecurity {
|
||||
class Transaction;
|
||||
namespace audit_log {
|
||||
namespace writer {
|
||||
class Writer;
|
||||
@ -177,6 +176,10 @@ class AuditLog {
|
||||
static int addParts(int parts, const std::string& new_parts);
|
||||
static int removeParts(int parts, const std::string& new_parts);
|
||||
|
||||
void setCtlAuditEngineActive() {
|
||||
m_ctlAuditEngineActive = true;
|
||||
}
|
||||
|
||||
bool merge(AuditLog *from, std::string *error);
|
||||
|
||||
std::string m_path1;
|
||||
@ -203,6 +206,7 @@ class AuditLog {
|
||||
std::string m_relevant;
|
||||
|
||||
audit_log::writer::Writer *m_writer;
|
||||
bool m_ctlAuditEngineActive; // rules have at least one action On or RelevantOnly
|
||||
};
|
||||
|
||||
|
||||
|
@ -49,6 +49,7 @@ typedef struct Rules_t RulesSet;
|
||||
#include "modsecurity/collection/collection.h"
|
||||
#include "modsecurity/variable_origin.h"
|
||||
#include "modsecurity/anchored_set_variable_translation_proxy.h"
|
||||
#include "modsecurity/audit_log.h"
|
||||
|
||||
|
||||
#ifndef NO_LOGS
|
||||
@ -529,6 +530,12 @@ class Transaction : public TransactionAnchoredVariables, public TransactionSecMa
|
||||
*/
|
||||
std::list< std::pair<int, std::string> > m_auditLogModifier;
|
||||
|
||||
/**
|
||||
* This transaction's most recent action ctl:auditEngine
|
||||
*
|
||||
*/
|
||||
audit_log::AuditLog::AuditLogStatus m_ctlAuditEngine;
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
@ -118,6 +118,7 @@ ACTIONS = \
|
||||
actions/capture.cc \
|
||||
actions/chain.cc \
|
||||
actions/ctl/audit_log_parts.cc \
|
||||
actions/ctl/audit_engine.cc \
|
||||
actions/ctl/rule_engine.cc \
|
||||
actions/ctl/request_body_processor_json.cc \
|
||||
actions/ctl/request_body_processor_xml.cc \
|
||||
|
63
src/actions/ctl/audit_engine.cc
Normal file
63
src/actions/ctl/audit_engine.cc
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* ModSecurity, http://www.modsecurity.org/
|
||||
* Copyright (c) 2022 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* If any of the files related to licensing are missing or if you have any
|
||||
* other questions related to licensing please contact Trustwave Holdings, Inc.
|
||||
* directly using the email address security@modsecurity.org.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "src/actions/ctl/audit_engine.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "modsecurity/rules_set_properties.h"
|
||||
#include "modsecurity/rules_set.h"
|
||||
#include "modsecurity/transaction.h"
|
||||
|
||||
namespace modsecurity {
|
||||
namespace actions {
|
||||
namespace ctl {
|
||||
|
||||
|
||||
bool AuditEngine::init(std::string *error) {
|
||||
|
||||
std::string what(m_parser_payload, 12, m_parser_payload.size() - 12);
|
||||
|
||||
if (what == "on") {
|
||||
m_auditEngine = audit_log::AuditLog::AuditLogStatus::OnAuditLogStatus;
|
||||
} else if (what == "off") {
|
||||
m_auditEngine = audit_log::AuditLog::AuditLogStatus::OffAuditLogStatus;
|
||||
} else if (what == "relevantonly") {
|
||||
m_auditEngine = audit_log::AuditLog::AuditLogStatus::RelevantOnlyAuditLogStatus;
|
||||
} else {
|
||||
error->assign("Internal error. Expected: On, Off or RelevantOnly; " \
|
||||
"got: " + m_parser_payload);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AuditEngine::evaluate(RuleWithActions *rule, Transaction *transaction) {
|
||||
std::stringstream a;
|
||||
a << "Setting SecAuditEngine to ";
|
||||
a << std::to_string(m_auditEngine);
|
||||
a << " as requested by a ctl:auditEngine action";
|
||||
|
||||
ms_dbg_a(transaction, 8, a.str());
|
||||
|
||||
transaction->m_ctlAuditEngine = m_auditEngine;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
} // namespace ctl
|
||||
} // namespace actions
|
||||
} // namespace modsecurity
|
51
src/actions/ctl/audit_engine.h
Normal file
51
src/actions/ctl/audit_engine.h
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* ModSecurity, http://www.modsecurity.org/
|
||||
* Copyright (c) 2022 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* If any of the files related to licensing are missing or if you have any
|
||||
* other questions related to licensing please contact Trustwave Holdings, Inc.
|
||||
* directly using the email address security@modsecurity.org.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "modsecurity/rules_set_properties.h"
|
||||
#include "modsecurity/actions/action.h"
|
||||
|
||||
#include "modsecurity/audit_log.h"
|
||||
|
||||
|
||||
#ifndef SRC_ACTIONS_CTL_AUDIT_ENGINE_H_
|
||||
#define SRC_ACTIONS_CTL_AUDIT_ENGINE_H_
|
||||
|
||||
namespace modsecurity {
|
||||
class Transaction;
|
||||
|
||||
namespace actions {
|
||||
namespace ctl {
|
||||
|
||||
|
||||
class AuditEngine : public Action {
|
||||
public:
|
||||
explicit AuditEngine(const std::string &action)
|
||||
: Action(action, RunTimeOnlyIfMatchKind),
|
||||
m_auditEngine(audit_log::AuditLog::AuditLogStatus::NotSetLogStatus) { }
|
||||
|
||||
bool init(std::string *error) override;
|
||||
bool evaluate(RuleWithActions *rule, Transaction *transaction) override;
|
||||
|
||||
audit_log::AuditLog::AuditLogStatus m_auditEngine;
|
||||
};
|
||||
|
||||
|
||||
} // namespace ctl
|
||||
} // namespace actions
|
||||
} // namespace modsecurity
|
||||
|
||||
#endif // SRC_ACTIONS_CTL_AUDIT_ENGINE_H_
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include "modsecurity/transaction.h"
|
||||
#include "modsecurity/rule_message.h"
|
||||
#include "src/audit_log/writer/https.h"
|
||||
#include "src/audit_log/writer/parallel.h"
|
||||
@ -61,7 +62,8 @@ AuditLog::AuditLog()
|
||||
m_status(NotSetLogStatus),
|
||||
m_type(NotSetAuditLogType),
|
||||
m_relevant(""),
|
||||
m_writer(NULL) { }
|
||||
m_writer(NULL),
|
||||
m_ctlAuditEngineActive(false) { }
|
||||
|
||||
|
||||
AuditLog::~AuditLog() {
|
||||
@ -210,7 +212,8 @@ bool AuditLog::setType(AuditLogType audit_type) {
|
||||
bool AuditLog::init(std::string *error) {
|
||||
audit_log::writer::Writer *tmp_writer;
|
||||
|
||||
if (m_status == OffAuditLogStatus || m_status == NotSetLogStatus) {
|
||||
if ((m_status == OffAuditLogStatus || m_status == NotSetLogStatus)
|
||||
&& !m_ctlAuditEngineActive) {
|
||||
if (m_writer) {
|
||||
delete m_writer;
|
||||
m_writer = NULL;
|
||||
@ -275,7 +278,13 @@ bool AuditLog::saveIfRelevant(Transaction *transaction) {
|
||||
|
||||
bool AuditLog::saveIfRelevant(Transaction *transaction, int parts) {
|
||||
bool saveAnyway = false;
|
||||
if (m_status == OffAuditLogStatus || m_status == NotSetLogStatus) {
|
||||
|
||||
AuditLogStatus transactionAuditLogStatus(m_status);
|
||||
if (transaction->m_ctlAuditEngine != NotSetLogStatus) {
|
||||
transactionAuditLogStatus = transaction->m_ctlAuditEngine;
|
||||
}
|
||||
|
||||
if (transactionAuditLogStatus == OffAuditLogStatus || transactionAuditLogStatus == NotSetLogStatus) {
|
||||
ms_dbg_a(transaction, 5, "Audit log engine was not set.");
|
||||
return true;
|
||||
}
|
||||
@ -287,7 +296,7 @@ bool AuditLog::saveIfRelevant(Transaction *transaction, int parts) {
|
||||
}
|
||||
}
|
||||
|
||||
if ((m_status == RelevantOnlyAuditLogStatus
|
||||
if ((transactionAuditLogStatus == RelevantOnlyAuditLogStatus
|
||||
&& this->isRelevant(transaction->m_httpCodeReturned) == false)
|
||||
&& saveAnyway == false) {
|
||||
ms_dbg_a(transaction, 9, "Return code `" +
|
||||
@ -353,6 +362,10 @@ bool AuditLog::merge(AuditLog *from, std::string *error) {
|
||||
m_format = from->m_format;
|
||||
}
|
||||
|
||||
if (from->m_ctlAuditEngineActive) {
|
||||
m_ctlAuditEngineActive = from->m_ctlAuditEngineActive;
|
||||
}
|
||||
|
||||
return init(error);
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -64,6 +64,7 @@ class Driver;
|
||||
#include "src/actions/block.h"
|
||||
#include "src/actions/capture.h"
|
||||
#include "src/actions/chain.h"
|
||||
#include "src/actions/ctl/audit_engine.h"
|
||||
#include "src/actions/ctl/audit_log_parts.h"
|
||||
#include "src/actions/ctl/request_body_access.h"
|
||||
#include "src/actions/ctl/rule_engine.h"
|
||||
@ -350,7 +351,7 @@ using namespace modsecurity::operators;
|
||||
a = std::move(c);
|
||||
|
||||
|
||||
#line 354 "seclang-parser.hh"
|
||||
#line 355 "seclang-parser.hh"
|
||||
|
||||
# include <cassert>
|
||||
# include <cstdlib> // std::abort
|
||||
@ -484,7 +485,7 @@ using namespace modsecurity::operators;
|
||||
#endif
|
||||
|
||||
namespace yy {
|
||||
#line 488 "seclang-parser.hh"
|
||||
#line 489 "seclang-parser.hh"
|
||||
|
||||
|
||||
|
||||
@ -8625,7 +8626,7 @@ switch (yykind)
|
||||
}
|
||||
|
||||
} // yy
|
||||
#line 8629 "seclang-parser.hh"
|
||||
#line 8630 "seclang-parser.hh"
|
||||
|
||||
|
||||
|
||||
|
@ -25,6 +25,7 @@ class Driver;
|
||||
#include "src/actions/block.h"
|
||||
#include "src/actions/capture.h"
|
||||
#include "src/actions/chain.h"
|
||||
#include "src/actions/ctl/audit_engine.h"
|
||||
#include "src/actions/ctl/audit_log_parts.h"
|
||||
#include "src/actions/ctl/request_body_access.h"
|
||||
#include "src/actions/ctl/rule_engine.h"
|
||||
@ -2625,18 +2626,17 @@ act:
|
||||
}
|
||||
| ACTION_CTL_AUDIT_ENGINE CONFIG_VALUE_ON
|
||||
{
|
||||
//ACTION_NOT_SUPPORTED("CtlAuditEngine", @0);
|
||||
ACTION_CONTAINER($$, new actions::Action($1));
|
||||
ACTION_CONTAINER($$, new actions::ctl::AuditEngine("ctl:auditengine=on"));
|
||||
driver.m_auditLog->setCtlAuditEngineActive();
|
||||
}
|
||||
| ACTION_CTL_AUDIT_ENGINE CONFIG_VALUE_OFF
|
||||
{
|
||||
//ACTION_NOT_SUPPORTED("CtlAuditEngine", @0);
|
||||
ACTION_CONTAINER($$, new actions::Action($1));
|
||||
ACTION_CONTAINER($$, new actions::ctl::AuditEngine("ctl:auditengine=off"));
|
||||
}
|
||||
| ACTION_CTL_AUDIT_ENGINE CONFIG_VALUE_RELEVANT_ONLY
|
||||
{
|
||||
//ACTION_NOT_SUPPORTED("CtlAuditEngine", @0);
|
||||
ACTION_CONTAINER($$, new actions::Action($1));
|
||||
ACTION_CONTAINER($$, new actions::ctl::AuditEngine("ctl:auditengine=relevantonly"));
|
||||
driver.m_auditLog->setCtlAuditEngineActive();
|
||||
}
|
||||
| ACTION_CTL_AUDIT_LOG_PARTS
|
||||
{
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -613,6 +613,7 @@ EQUALS_MINUS (?i:=\-)
|
||||
{CONFIG_VALUE_DETC} { return p::make_CONFIG_VALUE_DETC(yytext, *driver.loc.back()); }
|
||||
{CONFIG_VALUE_OFF} { return p::make_CONFIG_VALUE_OFF(yytext, *driver.loc.back()); }
|
||||
{CONFIG_VALUE_ON} { return p::make_CONFIG_VALUE_ON(yytext, *driver.loc.back()); }
|
||||
{CONFIG_VALUE_RELEVANT_ONLY} { return p::make_CONFIG_VALUE_RELEVANT_ONLY(yytext, *driver.loc.back()); }
|
||||
[ \t]*\\\n[ \t]* { driver.loc.back()->lines(1); driver.loc.back()->step(); }
|
||||
[ \t]*\\\r\n[ \t]* { driver.loc.back()->lines(1); driver.loc.back()->step(); }
|
||||
}
|
||||
|
@ -122,6 +122,7 @@ Transaction::Transaction(ModSecurity *ms, RulesSet *rules, void *logCbData)
|
||||
m_ruleRemoveTargetById(),
|
||||
m_requestBodyAccess(RulesSet::PropertyNotSetConfigBoolean),
|
||||
m_auditLogModifier(),
|
||||
m_ctlAuditEngine(AuditLog::AuditLogStatus::NotSetLogStatus),
|
||||
m_rulesMessages(),
|
||||
m_requestBody(),
|
||||
m_responseBody(),
|
||||
@ -195,6 +196,7 @@ Transaction::Transaction(ModSecurity *ms, RulesSet *rules, char *id, void *logCb
|
||||
m_ruleRemoveTargetById(),
|
||||
m_requestBodyAccess(RulesSet::PropertyNotSetConfigBoolean),
|
||||
m_auditLogModifier(),
|
||||
m_ctlAuditEngine(AuditLog::AuditLogStatus::NotSetLogStatus),
|
||||
m_rulesMessages(),
|
||||
m_requestBody(),
|
||||
m_responseBody(),
|
||||
|
@ -35,8 +35,8 @@ invalidScanfArgType_int:src/rules_set_properties.cc:102
|
||||
unmatchedSuppression:src/utils/geo_lookup.cc:82
|
||||
useInitializationList:src/utils/shared_files.h:87
|
||||
unmatchedSuppression:src/utils/msc_tree.cc
|
||||
functionStatic:headers/modsecurity/transaction.h:407
|
||||
duplicateBranch:src/audit_log/audit_log.cc:223
|
||||
functionStatic:headers/modsecurity/transaction.h:408
|
||||
duplicateBranch:src/audit_log/audit_log.cc:226
|
||||
unreadVariable:src/request_body_processor/multipart.cc:435
|
||||
stlcstrParam:src/audit_log/writer/parallel.cc:145
|
||||
functionStatic:src/engine/lua.h:70
|
||||
@ -54,7 +54,7 @@ duplicateBranch:src/request_body_processor/multipart.cc:93
|
||||
danglingTempReference:src/modsecurity.cc:206
|
||||
knownConditionTrueFalse:src/operators/validate_url_encoding.cc:77
|
||||
knownConditionTrueFalse:src/operators/verify_svnr.cc:87
|
||||
rethrowNoCurrentException:headers/modsecurity/transaction.h:306
|
||||
rethrowNoCurrentException:headers/modsecurity/transaction.h:307
|
||||
rethrowNoCurrentException:src/rule_with_actions.cc:123
|
||||
|
||||
noExplicitConstructor:seclang-parser.hh
|
||||
|
51
test/test-cases/regression/action-ctl_audit_engine.json
Normal file
51
test/test-cases/regression/action-ctl_audit_engine.json
Normal file
@ -0,0 +1,51 @@
|
||||
[
|
||||
{
|
||||
"enabled": 1,
|
||||
"version_min": 300000,
|
||||
"version_max": 0,
|
||||
"title": "auditengine : Config=Off, ctl:auditEngine=on",
|
||||
"client": {
|
||||
"ip": "200.249.12.31",
|
||||
"port": 2313
|
||||
},
|
||||
"server": {
|
||||
"ip": "200.249.12.31",
|
||||
"port": 80
|
||||
},
|
||||
"request": {
|
||||
"headers": {
|
||||
"Host": "www.modsecurity.org",
|
||||
"User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)",
|
||||
"Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8",
|
||||
"Accept-Language": "en-us,en;q=0.5",
|
||||
"Accept-Encoding": "gzip,deflate",
|
||||
"Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7",
|
||||
"Keep-Alive": "300",
|
||||
"Connection": "keep-alive",
|
||||
"Pragma": "no-cache",
|
||||
"Cache-Control": "no-cache"
|
||||
},
|
||||
"uri": "\/test.pl?parm1=test1&parm2=test2",
|
||||
"method": "GET",
|
||||
"http_version": 1.1,
|
||||
"body": ""
|
||||
},
|
||||
"expected": {
|
||||
"audit_log": "--A--",
|
||||
"error_log": "",
|
||||
"http_code": 200
|
||||
},
|
||||
"rules": [
|
||||
"SecRuleEngine On",
|
||||
"SecDefaultAction \"phase:2,nolog,pass\"",
|
||||
"SecAuditEngine Off",
|
||||
"SecAuditLogParts ABCFHZ",
|
||||
"SecAuditLog /tmp/modsec_test_ctl_auditengine_auditlog_1.log",
|
||||
"SecAuditLogDirMode 0766",
|
||||
"SecAuditLogFileMode 0666",
|
||||
"SecAuditLogType Serial",
|
||||
"SecAuditLogRelevantStatus \"^(?:5|4(?!04))\"",
|
||||
"SecRule ARGS \"@contains test2\" \"id:1701,phase:2,pass,nolog,ctl:auditEngine=on\""
|
||||
]
|
||||
}
|
||||
]
|
Loading…
x
Reference in New Issue
Block a user