Description
Working with the callback function the message
always contains a %d
instead of an error code.
ex: ModSecurity: Access denied with code %d (phase 2). Matched "Operator Rx with parameter a...
.
Even though in the audit log, the line will contain the code instead of %d
ex: ModSecurity: Access denied with code 200 (phase 2). Matched "Operator Rx with parameter a...
I am invoking the call back by:
#include <ctype.h>
#include <glob.h>
#include <arpa/inet.h>
#include <modsecurity/intervention.h>
#include <modsecurity/rules.h>
// data is an output stream that is needed to print
static void msc_callback(void *data, const void *message)
{
func(data, "%s", (const char *)message);
}
int main() {
const char *err;
ModSecurity *modsec = msc_init();
Rules *rules = msc_create_rules_set();
Transaction *txn = msc_new_transaction(waf->modsec, waf->rules, (void *)data);
msc_set_log_cb(modsec, (void *)msc_callback);
if (msc_rules_add_file(rules, pglob.gl_pathv[0], &err) < 0) {
printf("rules error: %s", err);
}
/*
... add and process request/response headers and bodies ...
*/
msc_process_logging(txn);
}
After some digging through the code for the process for the callback I found that the callback is only called through Transaction::serverLog()
which contains the function ModSecurity::serverLog(m_logCbData, rm)
. ModSecurity has no access/reference to the Transaction::m_httpCodeReturned
so it would have had to been passed by Transaction::serverLog()
with this->m_httpCodeReturned
to be able to be passed into the RuleMessage::log()
to generate the callback message. I believe this patch can (and has in small testing) fix it :
diff --git a/headers/modsecurity/modsecurity.h b/headers/modsecurity/modsecurity.h
index 8fa9e59..6157dae 100644
--- a/headers/modsecurity/modsecurity.h
+++ b/headers/modsecurity/modsecurity.h
@@ -289,7 +289,7 @@ class ModSecurity {
*/
void setServerLogCb(ModSecLogCb cb, int properties);
- void serverLog(void *data, std::shared_ptr<RuleMessage> rm);
+ void serverLog(void *data, std::shared_ptr<RuleMessage> rm, int httpCodeReturned);
const std::string& getConnectorInformation();
diff --git a/src/modsecurity.cc b/src/modsecurity.cc
index b079d01..9f9ddd4 100644
--- a/src/modsecurity.cc
+++ b/src/modsecurity.cc
@@ -184,7 +184,7 @@ const std::string& ModSecurity::getConnectorInformation() {
return m_connector;
}
-void ModSecurity::serverLog(void *data, std::shared_ptr<RuleMessage> rm) {
+void ModSecurity::serverLog(void *data, std::shared_ptr<RuleMessage> rm, int httpCodeReturned) {
if (m_logCb == NULL) {
std::cerr << "Server log callback is not set -- " << rm->errorLog();
std::cerr << std::endl;
@@ -196,7 +196,7 @@ void ModSecurity::serverLog(void *data, std::shared_ptr<RuleMessage> rm) {
}
if (m_logProperties & TextLogProperty) {
- std::string &&d = rm->log();
+ std::string &&d = rm->log(0, httpCodeReturned);
const void *a = static_cast<const void *>(d.c_str());
m_logCb(data, a);
return;
diff --git a/src/transaction.cc b/src/transaction.cc
index 1bba7e3..aaa7b57 100644
--- a/src/transaction.cc
+++ b/src/transaction.cc
@@ -1736,7 +1736,7 @@ std::string Transaction::toJSON(int parts) {
void Transaction::serverLog(std::shared_ptr<RuleMessage> rm) {
- m_ms->serverLog(m_logCbData, rm);
+ m_ms->serverLog(m_logCbData, rm, this->m_httpCodeReturned);
}
Though I am unsure how/if props should be set or in ModSecurity::serverLog()
. I am also unsure in the case that RuleMessageLogProperty
is set, how to pass the m_httpCodeReturned
to the rule message or callback function. Possibly overloading the callback function to contain a third parameter for the return code.
I also noticed redundant if statement here.