Add remove whitelist action to WAF logs
This commit is contained in:
@@ -295,6 +295,46 @@ class Waf extends Page implements HasForms, HasTable
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function ruleMatchesEntry(array $rule, array $entry): bool
|
||||||
|
{
|
||||||
|
if (!is_array($rule)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (isset($rule['enabled']) && !$rule['enabled']) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$ruleId = (string) ($entry['rule_id'] ?? '');
|
||||||
|
$uri = (string) ($entry['uri'] ?? '');
|
||||||
|
$host = (string) ($entry['host'] ?? '');
|
||||||
|
$ip = (string) ($entry['remote_ip'] ?? '');
|
||||||
|
|
||||||
|
$idsRaw = (string) ($rule['rule_ids'] ?? '');
|
||||||
|
$ids = preg_split('/[,\s]+/', $idsRaw, -1, PREG_SPLIT_NO_EMPTY) ?: [];
|
||||||
|
$ids = array_map('trim', $ids);
|
||||||
|
if ($ruleId !== '' && !empty($ids) && !in_array($ruleId, $ids, true)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$matchType = (string) ($rule['match_type'] ?? '');
|
||||||
|
$matchValue = (string) ($rule['match_value'] ?? '');
|
||||||
|
|
||||||
|
if ($matchType === 'ip' && $matchValue !== '' && $this->ipMatches($ip, $matchValue)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ($matchType === 'uri_exact' && $matchValue !== '' && $uri === $matchValue) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ($matchType === 'uri_prefix' && $matchValue !== '' && str_starts_with($uri, $matchValue)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ($matchType === 'host' && $matchValue !== '' && $host === $matchValue) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
protected function ipMatches(string $ip, string $rule): bool
|
protected function ipMatches(string $ip, string $rule): bool
|
||||||
{
|
{
|
||||||
if ($ip === '' || $rule === '') {
|
if ($ip === '' || $rule === '') {
|
||||||
@@ -376,6 +416,50 @@ class Waf extends Page implements HasForms, HasTable
|
|||||||
->send();
|
->send();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function removeWhitelistEntry(array $record): void
|
||||||
|
{
|
||||||
|
$rules = $this->getWhitelistRules();
|
||||||
|
$beforeCount = count($rules);
|
||||||
|
|
||||||
|
$rules = array_values(array_filter($rules, function (array $rule) use ($record): bool {
|
||||||
|
return ! $this->ruleMatchesEntry($rule, $record);
|
||||||
|
}));
|
||||||
|
|
||||||
|
if (count($rules) === $beforeCount) {
|
||||||
|
Notification::make()
|
||||||
|
->title(__('No matching whitelist rule found'))
|
||||||
|
->warning()
|
||||||
|
->send();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Setting::set('waf_whitelist_rules', json_encode(array_values($rules), JSON_UNESCAPED_SLASHES));
|
||||||
|
$this->wafFormData['whitelist_rules'] = $rules;
|
||||||
|
|
||||||
|
try {
|
||||||
|
$agent = new AgentClient;
|
||||||
|
$agent->wafApplySettings(
|
||||||
|
Setting::get('waf_enabled', '0') === '1',
|
||||||
|
(string) Setting::get('waf_paranoia', '1'),
|
||||||
|
Setting::get('waf_audit_log', '1') === '1',
|
||||||
|
$rules
|
||||||
|
);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
Notification::make()
|
||||||
|
->title(__('Whitelist updated, but apply failed'))
|
||||||
|
->body($e->getMessage())
|
||||||
|
->warning()
|
||||||
|
->send();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->auditEntries = $this->markWhitelisted($this->auditEntries);
|
||||||
|
|
||||||
|
Notification::make()
|
||||||
|
->title(__('Whitelist removed'))
|
||||||
|
->success()
|
||||||
|
->send();
|
||||||
|
}
|
||||||
|
|
||||||
public function table(Table $table): Table
|
public function table(Table $table): Table
|
||||||
{
|
{
|
||||||
return $table
|
return $table
|
||||||
@@ -435,6 +519,13 @@ class Waf extends Page implements HasForms, HasTable
|
|||||||
->color('primary')
|
->color('primary')
|
||||||
->visible(fn (array $record): bool => empty($record['whitelisted']))
|
->visible(fn (array $record): bool => empty($record['whitelisted']))
|
||||||
->action(fn (array $record) => $this->whitelistEntry($record)),
|
->action(fn (array $record) => $this->whitelistEntry($record)),
|
||||||
|
\Filament\Actions\Action::make('removeWhitelist')
|
||||||
|
->label(__('Remove whitelist'))
|
||||||
|
->icon('heroicon-o-x-mark')
|
||||||
|
->color('danger')
|
||||||
|
->visible(fn (array $record): bool => !empty($record['whitelisted']))
|
||||||
|
->requiresConfirmation()
|
||||||
|
->action(fn (array $record) => $this->removeWhitelistEntry($record)),
|
||||||
])
|
])
|
||||||
->emptyStateHeading(__('No blocked rules found'))
|
->emptyStateHeading(__('No blocked rules found'))
|
||||||
->emptyStateDescription(__('No ModSecurity denials found in the audit log.'))
|
->emptyStateDescription(__('No ModSecurity denials found in the audit log.'))
|
||||||
|
|||||||
Reference in New Issue
Block a user