remove DetectionOnly WAF mode

DetectionOnly was fundamentally broken in coraza-caddy (actually blocks
requests via anomaly scoring), caused massive audit log flooding, and the
threshold workaround had several issues:
- t:none is meaningless in a SecAction (no target to transform)
- SecRuleEngine directive ordering relative to SecAction is implementation-
  defined, making the override fragile
- host.mode ?? 'DetectionOnly' fallbacks silently gave any host without an
  explicit mode the broken DetectionOnly behaviour

Changes:
- Remove DetectionOnly from UI (global settings radio, per-host engine mode)
- Coerce legacy DB values of 'DetectionOnly' to 'On' in buildWafHandler
- Fix fallback defaults: host.mode ?? 'DetectionOnly' → host.mode ?? 'On'
- Fix action parsers: unknown mode defaults to 'On' (was 'DetectionOnly')
- Fix global settings defaultValue: ?? 'DetectionOnly' → ?? 'On' (or 'Off')
- Remove the fragile threshold SecAction workaround
- Update types: mode is now 'Off' | 'On' throughout

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
fuomag9
2026-03-06 17:27:08 +01:00
parent 5cd92fe669
commit b348dae4be
8 changed files with 14 additions and 22 deletions

View File

@@ -20,7 +20,7 @@ import { type WafHostConfig } from "@/src/lib/models/proxy-hosts";
import { WafRuleExclusions } from "./WafRuleExclusions";
type WafMode = "merge" | "override";
type EngineMode = "Off" | "DetectionOnly" | "On" | "inherit";
type EngineMode = "Off" | "On" | "inherit";
const QUICK_TEMPLATES = [
{ label: "Allow IP", snippet: `SecRule REMOTE_ADDR "@ipMatch 1.2.3.4" "id:9000,phase:1,allow,nolog,msg:'Allow IP'"` },
@@ -154,7 +154,7 @@ export function WafFields({ value, showModeSelector = true }: Props) {
Engine Mode
</Typography>
<Stack direction="row" spacing={1} mt={0.75}>
{(["inherit", "Off", "DetectionOnly", "On"] as EngineMode[]).map((v) => (
{(["inherit", "Off", "On"] as EngineMode[]).map((v) => (
<Box
key={v}
onClick={() => setEngineMode(v)}
@@ -187,7 +187,7 @@ export function WafFields({ value, showModeSelector = true }: Props) {
color={engineMode === v ? "error.main" : "text.secondary"}
sx={{ transition: "all 0.15s ease", fontSize: "0.8rem" }}
>
{v === "DetectionOnly" ? "Detect only" : v === "inherit" ? "Global default" : v}
{v === "inherit" ? "Global default" : v}
</Typography>
</Box>
))}