feat(waf): CRS-App-Exclusion-Plugins (Nextcloud/WordPress/Drupal) pro Domain — v1.3.12
Statt manueller SecRuleRemoveById-IDs kann man pro Domain offizielle OWASP-CRS- Exclusion-Plugins aktivieren — pfad-genaue, upstream-gepflegte App-Ausnahmen. - Migration 0046: waf_configs.crs_plugins text[]. - Engine (engine.go): je gewähltem Plugin werden config/before VOR den CRS-Rules und after DANACH inkludiert (exakt nach OWASP-CRS-Plugin-Spec); nur die für DIESE Domain gewählten, nur wenn die Datei existiert. Whitelist KnownCRSPlugins. - Handler: crs_plugins im Upsert-Body + Whitelist-Validierung (Include-Pfad- Injection-Schutz). - Packaging (postinst): lädt die Plugins (coreruleset/<name>-plugin) nach <crs>/plugins/ — self-healing auf jedem configure, nur fehlende. - UI: Multi-Select „App-Profile (CRS-Plugins)" im WAF-Config-Drawer. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1934,6 +1934,9 @@
|
||||
"enabled": "Aktiviert",
|
||||
"mode": "Modus",
|
||||
"paranoia": "Paranoia-Level",
|
||||
"crsPlugins": "App-Profile (CRS-Plugins)",
|
||||
"crsPluginsHint": "Offizielle OWASP-CRS-Exclusion-Plugins für bekannte Apps — deaktivieren automatisch die typischen False-Positive-Regeln pfad-genau (z.B. Nextcloud-WebDAV, WordPress-Editor). Sauberer als manuelle Regel-IDs.",
|
||||
"crsPluginsPlaceholder": "App-Profile wählen (optional)",
|
||||
"exclusions": "Regel-Ausnahmen",
|
||||
"exclusionsHint": "Kommagetrennte Regel-IDs die deaktiviert werden (z.B. 920350, 941130).",
|
||||
"trustedProxies": "Vertrauenswürdige Proxys",
|
||||
|
||||
@@ -1934,6 +1934,9 @@
|
||||
"enabled": "Enabled",
|
||||
"mode": "Mode",
|
||||
"paranoia": "Paranoia Level",
|
||||
"crsPlugins": "App profiles (CRS plugins)",
|
||||
"crsPluginsHint": "Official OWASP CRS exclusion plugins for well-known apps — automatically disable the typical false-positive rules in a path-scoped way (e.g. Nextcloud WebDAV, WordPress editor). Cleaner than manual rule IDs.",
|
||||
"crsPluginsPlaceholder": "Select app profiles (optional)",
|
||||
"exclusions": "Rule Exclusions",
|
||||
"exclusionsHint": "Comma-separated rule IDs to disable (e.g. 920350, 941130).",
|
||||
"trustedProxies": "Trusted Proxies",
|
||||
|
||||
@@ -33,11 +33,19 @@ interface WafConfig {
|
||||
mode: 'detection' | 'blocking'
|
||||
paranoia_level: number
|
||||
rule_exclusions: string[]
|
||||
crs_plugins: string[]
|
||||
exclusion_notes: Record<string, string>
|
||||
trusted_proxies: string[]
|
||||
custom_rules: string
|
||||
}
|
||||
|
||||
// CRS-App-Exclusion-Plugins — muss zur Backend-Whitelist (KnownCRSPlugins) passen.
|
||||
const CRS_PLUGIN_OPTIONS = [
|
||||
{ value: 'nextcloud', label: 'Nextcloud' },
|
||||
{ value: 'wordpress', label: 'WordPress' },
|
||||
{ value: 'drupal', label: 'Drupal' },
|
||||
]
|
||||
|
||||
// ---------- API helpers -----------------------------------------------------
|
||||
|
||||
async function fetchDomains(): Promise<Domain[]> {
|
||||
@@ -65,6 +73,7 @@ function defaultConfig(domainId: number): WafConfig {
|
||||
mode: 'detection',
|
||||
paranoia_level: 1,
|
||||
rule_exclusions: [],
|
||||
crs_plugins: [],
|
||||
exclusion_notes: {},
|
||||
trusted_proxies: [],
|
||||
custom_rules: '',
|
||||
@@ -75,6 +84,7 @@ interface WafFormValues {
|
||||
enabled: boolean
|
||||
mode: 'detection' | 'blocking'
|
||||
paranoia_level: number
|
||||
crs_plugins: string[]
|
||||
trusted_proxies_str: string
|
||||
custom_rules: string
|
||||
}
|
||||
@@ -147,6 +157,7 @@ function ConfigDrawer({ domainName, domainId, onClose }: ConfigDrawerProps) {
|
||||
mode: vals.mode,
|
||||
paranoia_level: vals.paranoia_level,
|
||||
rule_exclusions: cfg?.rule_exclusions ?? [],
|
||||
crs_plugins: vals.crs_plugins ?? [],
|
||||
exclusion_notes: cfg?.exclusion_notes ?? {},
|
||||
trusted_proxies: proxies,
|
||||
custom_rules: vals.custom_rules ?? '',
|
||||
@@ -190,6 +201,20 @@ function ConfigDrawer({ domainName, domainId, onClose }: ConfigDrawerProps) {
|
||||
</Select>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
label={t('waf.config.crsPlugins')}
|
||||
name="crs_plugins"
|
||||
help={t('waf.config.crsPluginsHint')}
|
||||
>
|
||||
<Select
|
||||
mode="multiple"
|
||||
allowClear
|
||||
disabled={isViewer}
|
||||
placeholder={t('waf.config.crsPluginsPlaceholder')}
|
||||
options={CRS_PLUGIN_OPTIONS}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
{/* Exclusions list — shows existing exclusions with notes + remove button */}
|
||||
<Form.Item label={t('waf.config.exclusions')}>
|
||||
{(cfg?.rule_exclusions ?? []).length === 0 ? (
|
||||
@@ -224,6 +249,7 @@ function ConfigDrawer({ domainName, domainId, onClose }: ConfigDrawerProps) {
|
||||
mode: cfg?.mode ?? 'detection',
|
||||
paranoia_level: cfg?.paranoia_level ?? 1,
|
||||
rule_exclusions: newExclusions,
|
||||
crs_plugins: cfg?.crs_plugins ?? [],
|
||||
exclusion_notes: newNotes,
|
||||
trusted_proxies: cfg?.trusted_proxies ?? [],
|
||||
custom_rules: cfg?.custom_rules ?? '',
|
||||
|
||||
Reference in New Issue
Block a user