Merge pull request #3464 from airween/v3/encodejsaudit

fix: encode possible binary characters from user input in audit logs
This commit is contained in:
Ervin Hegedus
2025-11-14 09:22:46 +01:00
committed by GitHub
3 changed files with 191 additions and 5 deletions

View File

@@ -112,7 +112,7 @@ std::string Operator::resolveMatchMessage(Transaction *t,
if (m_couldContainsMacro == false) {
ret = "Matched \"Operator `" + m_op + "' with parameter `" +
utils::string::limitTo(200, m_param) +
"' against variable `" + key + "' (Value: `" +
"' against variable `" + utils::string::toHexIfNeeded(key) + "' (Value: `" +
utils::string::limitTo(100,
utils::string::toHexIfNeeded(value)) + \
"' )";
@@ -120,7 +120,7 @@ std::string Operator::resolveMatchMessage(Transaction *t,
std::string p(m_string->evaluate(t));
ret = "Matched \"Operator `" + m_op + "' with parameter `" +
utils::string::limitTo(200, p) +
"' against variable `" + key + "' (Value: `" +
"' against variable `" + utils::string::toHexIfNeeded(key) + "' (Value: `" +
utils::string::limitTo(100,
utils::string::toHexIfNeeded(value)) +
"' )";

View File

@@ -1610,7 +1610,7 @@ std::string Transaction::toJSON(int parts) {
if (parts & audit_log::AuditLog::CAuditLogPart) {
// FIXME: check for the binary content size.
LOGFY_ADD("body", this->m_requestBody.str());
LOGFY_ADD("body", utils::string::toHexIfNeeded(this->m_requestBody.str()));
}
/* request headers */
@@ -1622,7 +1622,7 @@ std::string Transaction::toJSON(int parts) {
m_variableRequestHeaders.resolve(&l);
for (auto &h : l) {
LOGFY_ADD(h->getKey().c_str(), h->getValue());
LOGFY_ADD(utils::string::toHexIfNeeded(h->getKey().c_str()).c_str(), utils::string::toHexIfNeeded(h->getValue()));
delete h;
}
@@ -1712,7 +1712,7 @@ std::string Transaction::toJSON(int parts) {
LOGFY_ADD("ruleId", std::to_string(a.m_rule.m_ruleId));
LOGFY_ADD("file", a.m_rule.getFileName());
LOGFY_ADD("lineNumber", std::to_string(a.m_rule.getLineNumber()));
LOGFY_ADD("data", a.m_data);
LOGFY_ADD("data", utils::string::toHexIfNeeded(a.m_data));
LOGFY_ADD("severity", std::to_string(a.m_severity));
LOGFY_ADD("ver", a.m_rule.m_ver);
LOGFY_ADD("rev", a.m_rule.m_rev);

View File

@@ -536,5 +536,191 @@
"SecAuditLogType Serial",
"SecAuditLogRelevantStatus \"^(?:5|4(?!04))\""
]
},
{
"enabled": 1,
"version_min": 300000,
"version_max": 0,
"title": "auditlog : Binary char from input, check 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": "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": "\/?%ADd+allow%3d1+%ADd+auto",
"method": "GET",
"http_version": 1.1,
"body": ""
},
"response": {
"headers": {
"Content-Type": "plain\/text\n\r"
},
"body": [
"test"
]
},
"expected": {
"audit_log": "\"match\":\"Matched \\\\\"Operator `ValidateUtf8Encoding' with parameter `' against variable `ARGS_NAMES:\\\\\\\\xadd allow=1 \\\\\\\\xadd auto' \\(Value: `\\\\\\\\xadd allow=1 \\\\\\\\xadd auto' \\)\"",
"debug_log": "",
"error_log": "",
"http_code": 403
},
"rules": [
"SecRuleEngine On",
"SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES \"@validateUtf8Encoding\" \"id:920250,phase:2,deny,t:none,msg:'UTF8 Encoding Abuse Attack Attempt',logdata:'%{MATCHED_VAR}'",
"SecAuditEngine RelevantOnly",
"SecAuditLogParts ABHJZ",
"SecAuditLogFormat JSON",
"SecAuditLogStorageDir /tmp/test",
"SecAuditLog /tmp/audit_test_prefix.log",
"SecAuditLogDirMode 0766",
"SecAuditLogFileMode 0600",
"SecAuditLogType Serial",
"SecAuditLogRelevantStatus \"^(?:5|4(?!04))\""
]
},
{
"enabled": 1,
"version_min": 300000,
"version_max": 0,
"title": "auditlog : Binary char from input, check body",
"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",
"Content-Type": "application/x-www-form-urlencoded",
"Content-Length": "3"
},
"uri": "\/?attack=true",
"method": "POST",
"http_version": 1.1,
"body": [
"\u00ad=\u00ad"
]
},
"response": {
"headers": {
"Content-Type": "plain\/text\n\r"
},
"body": [
"test"
]
},
"expected": {
"audit_log": "\"body\":\"\\\\\\\\xc2\\\\\\\\xad=\\\\\\\\xc2\\\\\\\\xad\\\\\\\\x0a",
"debug_log": "",
"error_log": "",
"http_code": 403
},
"rules": [
"SecRuleEngine On",
"SecRule ARGS_NAMES \"@rx attack\" \"id:1,phase:2,deny,t:none",
"SecAuditEngine RelevantOnly",
"SecAuditLogParts ABCHJZ",
"SecAuditLogFormat JSON",
"SecAuditLogStorageDir /tmp/test",
"SecAuditLog /tmp/audit_test_prefix.log",
"SecAuditLogDirMode 0766",
"SecAuditLogFileMode 0600",
"SecAuditLogType Serial",
"SecAuditLogRelevantStatus \"^(?:5|4(?!04))\""
]
},
{
"enabled": 1,
"version_min": 300000,
"version_max": 0,
"title": "auditlog : Binary char from input, check header",
"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",
"Content-Type": "application/x-www-form-urlencoded",
"Content-Length": "3",
"X-\u00ad-custom": "Some \u00ad value"
},
"uri": "\/?attack=true",
"method": "POST",
"http_version": 1.1,
"body": [
"\u00ad=\u00ad"
]
},
"response": {
"headers": {
"Content-Type": "plain\/text\n\r"
},
"body": [
"test"
]
},
"expected": {
"audit_log": "\"X-\\\\\\\\xc2\\\\\\\\xad-custom\":\"Some \\\\\\\\xc2\\\\\\\\xad value\"",
"debug_log": "",
"error_log": "",
"http_code": 403
},
"rules": [
"SecRuleEngine On",
"SecRule ARGS|ARGS_NAMES \"@rx attack\" \"id:1,phase:2,deny,t:none",
"SecAuditEngine RelevantOnly",
"SecAuditLogParts ABHJZ",
"SecAuditLogFormat JSON",
"SecAuditLogStorageDir /tmp/test",
"SecAuditLog /tmp/audit_test_prefix.log",
"SecAuditLogDirMode 0766",
"SecAuditLogFileMode 0600",
"SecAuditLogType Serial",
"SecAuditLogRelevantStatus \"^(?:5|4(?!04))\""
]
}
]