diff --git a/src/operators/operator.cc b/src/operators/operator.cc index 935add621..729104239 100644 --- a/src/operators/operator.cc +++ b/src/operators/operator.cc @@ -109,8 +109,9 @@ std::string Operator::resolveMatchMessage(Transaction *t, std::string ret = m_match_message; if (ret.empty() == true) { + const std::string opName = (m_negation ? "!" : "") + m_op; if (m_couldContainsMacro == false) { - ret = "Matched \"Operator `" + m_op + "' with parameter `" + + ret = "Matched \"Operator `" + opName + "' with parameter `" + utils::string::limitTo(200, m_param) + "' against variable `" + utils::string::toHexIfNeeded(key) + "' (Value: `" + utils::string::limitTo(100, @@ -118,7 +119,7 @@ std::string Operator::resolveMatchMessage(Transaction *t, "' )"; } else { std::string p(m_string->evaluate(t)); - ret = "Matched \"Operator `" + m_op + "' with parameter `" + + ret = "Matched \"Operator `" + opName + "' with parameter `" + utils::string::limitTo(200, p) + "' against variable `" + utils::string::toHexIfNeeded(key) + "' (Value: `" + utils::string::limitTo(100, diff --git a/src/rule_with_operator.cc b/src/rule_with_operator.cc index 9c356b8fb..90793446f 100644 --- a/src/rule_with_operator.cc +++ b/src/rule_with_operator.cc @@ -227,6 +227,8 @@ bool RuleWithOperator::evaluate(Transaction *trans, return true; } + const std::string opName = (m_operator->m_negation ? "!" : "") + m_operator->m_op; + if (m_operator->m_string) { eparam = m_operator->m_string->evaluate(trans); @@ -236,15 +238,16 @@ bool RuleWithOperator::evaluate(Transaction *trans, } else { eparam = "\"" + eparam + "\""; } - ms_dbg_a(trans, 4, "(Rule: " + std::to_string(m_ruleId) \ - + ") Executing operator \"" + getOperatorName() \ - + "\" with param " \ - + eparam \ - + " against " \ - + m_variables + "."); + + ms_dbg_a(trans, 4, "(Rule: " + std::to_string(m_ruleId) \ + + ") Executing operator \"" + opName \ + + "\" with param " \ + + eparam \ + + " against " \ + + m_variables + "."); } else { ms_dbg_a(trans, 4, "(Rule: " + std::to_string(m_ruleId) \ - + ") Executing operator \"" + getOperatorName() \ + + ") Executing operator \"" + opName \ + " against " \ + m_variables + "."); } diff --git a/test/test-cases/regression/auditlog.json b/test/test-cases/regression/auditlog.json index f4d660987..8b55bf81d 100644 --- a/test/test-cases/regression/auditlog.json +++ b/test/test-cases/regression/auditlog.json @@ -883,5 +883,56 @@ "SecAuditLogFileMode 0600", "SecAuditLogType Serial" ] + }, + { + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "auditlog : negated operator is rendered with `!` prefix in match message", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "www.modsecurity.org", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/test.pl?param1=hello", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Type": "plain/text\n\r", + "Content-Length": "4" + }, + "body": [ + "test" + ] + }, + "expected": { + "audit_log": "Operator `!Contains'", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"!@contains world\" \"id:1902,phase:1,deny,auditlog\"", + "SecAuditEngine On", + "SecAuditLogParts ABCFHZ", + "SecAuditLog /tmp/audit_test_negated_operator.log", + "SecAuditLogDirMode 0766", + "SecAuditLogFileMode 0600", + "SecAuditLogType Serial" + ] } ] diff --git a/test/test-cases/regression/operator-rx.json b/test/test-cases/regression/operator-rx.json index 917a67d1b..2a70bfebd 100644 --- a/test/test-cases/regression/operator-rx.json +++ b/test/test-cases/regression/operator-rx.json @@ -83,8 +83,8 @@ ] }, "expected": { - "debug_log": "Executing operator \"Rx\" with param \"\\^0\\$\"", - "error_log": "Matched \"Operator `Rx' with parameter `\\^0\\$'", + "debug_log": "Executing operator \"!Rx\" with param \"\\^0\\$\"", + "error_log": "Matched \"Operator `!Rx' with parameter `\\^0\\$'", "http_code": 200 }, "rules": [