diff --git a/bin/jabali-agent b/bin/jabali-agent index 8467ba4..a653efa 100755 --- a/bin/jabali-agent +++ b/bin/jabali-agent @@ -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);