Show real WAF rule hits for blocked requests

This commit is contained in:
root
2026-01-30 23:28:45 +02:00
parent f8c9a5c6e3
commit 1b350a1ef9

View File

@@ -747,6 +747,9 @@ function wafAuditLogList(array $params): array
'host' => null,
'uri' => null,
];
$contexts = [];
$hits = [];
$blocks = [];
foreach ($lines as $line) {
if (preg_match('/^---[A-Za-z0-9]+---A--$/', $line)) {
@@ -778,39 +781,88 @@ function wafAuditLogList(array $params): array
continue;
}
if (str_contains($line, 'ModSecurity:') && str_contains($line, 'Access denied')) {
$entry = [
if (!str_contains($line, 'ModSecurity:')) {
continue;
}
$uniqueId = null;
if (preg_match('/\\[unique_id "([^"]+)"\\]/', $line, $matches)) {
$uniqueId = $matches[1];
}
if ($uniqueId !== null && !isset($contexts[$uniqueId])) {
$contexts[$uniqueId] = [
'timestamp' => $current['timestamp'],
'remote_ip' => $current['remote_ip'],
'host' => $current['host'],
'uri' => $current['uri'],
'rule_id' => null,
'message' => null,
'severity' => null,
];
if (preg_match('/\\[id "([0-9]+)"\\]/', $line, $matches)) {
$entry['rule_id'] = $matches[1];
}
if (preg_match('/\\[msg "([^"]+)"\\]/', $line, $matches)) {
$entry['message'] = $matches[1];
}
if (preg_match('/\\[severity "([^"]+)"\\]/', $line, $matches)) {
$entry['severity'] = $matches[1];
}
if (preg_match('/\\[uri "([^"]+)"\\]/', $line, $matches)) {
$loggedUri = $matches[1];
$currentUri = (string) ($entry['uri'] ?? '');
if ($currentUri === '' || (!str_contains($currentUri, '?') && $loggedUri !== '')) {
$entry['uri'] = $loggedUri;
}
}
if (preg_match('/\\[hostname "([^"]+)"\\]/', $line, $matches)) {
$entry['host'] = $matches[1];
}
$entries[] = $entry;
}
$entry = [
'timestamp' => $current['timestamp'],
'remote_ip' => $current['remote_ip'],
'host' => $current['host'],
'uri' => $current['uri'],
'rule_id' => null,
'message' => null,
'severity' => null,
'unique_id' => $uniqueId,
];
if ($uniqueId !== null && isset($contexts[$uniqueId])) {
$entry = array_merge($entry, $contexts[$uniqueId]);
}
if (preg_match('/\\[id "([0-9]+)"\\]/', $line, $matches)) {
$entry['rule_id'] = $matches[1];
}
if (preg_match('/\\[msg "([^"]+)"\\]/', $line, $matches)) {
$entry['message'] = $matches[1];
}
if (preg_match('/\\[severity "([^"]+)"\\]/', $line, $matches)) {
$entry['severity'] = $matches[1];
}
if (preg_match('/\\[uri "([^"]+)"\\]/', $line, $matches)) {
$loggedUri = $matches[1];
$currentUri = (string) ($entry['uri'] ?? '');
if ($currentUri === '' || (!str_contains($currentUri, '?') && $loggedUri !== '')) {
$entry['uri'] = $loggedUri;
}
}
if (preg_match('/\\[hostname "([^"]+)"\\]/', $line, $matches)) {
$entry['host'] = $matches[1];
}
if (str_contains($line, 'Access denied')) {
if ($uniqueId !== null) {
$blocks[$uniqueId] = $entry;
} else {
$entries[] = $entry;
}
continue;
}
if (str_contains($line, 'Warning.')) {
if ($uniqueId !== null) {
$hits[$uniqueId][] = $entry;
} else {
$entries[] = $entry;
}
}
}
foreach ($blocks as $uniqueId => $blockEntry) {
if (!empty($hits[$uniqueId])) {
foreach ($hits[$uniqueId] as $hitEntry) {
$hitEntry['blocked'] = true;
$entries[] = $hitEntry;
}
continue;
}
$blockEntry['blocked'] = true;
$entries[] = $blockEntry;
}
$entries = array_reverse($entries);