NGINX + ModSecurity v3 + OWASP CRS unter Ubuntu 24.04 LTS – Schritt für Schritt – Teil 3

Teil 3 – Ausnahmen für WordPress korrekt setzen.

Nachdem du ModSecurity erfolgreich mit dem OWASP Core Rule Set (CRS) integriert und getestet hast, wirst du bei dynamischen Anwendungen wie WordPress schnell auf ein bekanntes Problem stoßen: false positives – also legitime Anfragen, die fälschlich als Angriff eingestuft und blockiert werden.

WordPress nutzt moderne Funktionen wie REST-API, AJAX, dynamische Blockeditoren (Gutenberg) und teils auch sehr spezielle HTML-Kommentare. Diese Mechanismen lösen bei aktivem CRS häufig Sicherheitsregeln aus, insbesondere in den Bereichen XSS, LFI oder Anomalieerkennung. Damit die Schutzmechanismen nicht zur Einschränkung im Admin-Bereich führen, müssen wir gezielt Regelausnahmen für WordPress definieren.

Vorgehensweise: WordPress-Ausnahmen sauber konfigurieren

Damit diese Ausnahmen nur für WordPress-Websites gelten, legen wir sie in einer separaten Datei ab und binden sie in die nginx.conf oder VirtualHost-Dateien gezielt ein.

1. Datei für Ausnahmen anlegen

Erstelle (oder bearbeite) die Datei:

Bash
sudo nano /etc/nginx/modsec/wp-admin-exceptions.conf

Und füge folgende Regeln ein:

wp-admin-exceptions.conf
# WordPress-specific ModSecurity exceptions to reduce false positives

# Disable ModSecurity for admin/editor and REST API requests (to reduce false positives and speed up backend)
SecRule REQUEST_URI "@rx ^/(wp-admin|wp-json|wp-includes|wp-content|wp-cron\.php)" \
    "id:1000990,phase:1,pass,nolog,noauditlog,ctl:auditEngine=Off,ctl:requestBodyAccess=Off"

# Global rule to disable audit logging for all WordPress requests
SecRule REQUEST_URI "@rx ^/wp-(admin|json|includes|content)" "id:1001000,phase:1,pass,nolog,noauditlog,ctl:auditEngine=Off"

# Allow REST API (used by Gutenberg and AJAX calls)
SecRule REQUEST_URI "@beginsWith /wp-json/" "id:1001001,phase:1,pass,nolog,noauditlog,ctl:auditEngine=Off,\
  ctl:ruleRemoveById=941180,\
  ctl:ruleRemoveById=920450,\
  ctl:ruleRemoveById=949110,\
  ctl:ruleRemoveById=920100,\
  ctl:ruleRemoveById=200005,\
  ctl:ruleRemoveById=920540,\
  ctl:ruleRemoveById=942100,\
  ctl:ruleRemoveById=941100,\
  ctl:ruleRemoveById=930100,\
  ctl:ruleRemoveById=930130,\
  ctl:ruleRemoveById=932250"

# Allow wp-admin (editor, dashboard, media, etc.)
SecRule REQUEST_URI "@beginsWith /wp-admin/" "id:1001002,phase:1,pass,nolog,noauditlog,ctl:auditEngine=Off,\
  msg:'WordPress REST API Exception',\
  ctl:ruleRemoveById=941180,\
  ctl:ruleRemoveById=920450,\
  ctl:ruleRemoveById=949110,\
  ctl:ruleRemoveById=920100,\
  ctl:ruleRemoveById=200005,\
  ctl:ruleRemoveById=920540,\
  ctl:ruleRemoveById=942100,\
  ctl:ruleRemoveById=941100,\
  ctl:ruleRemoveById=930100,\
  ctl:ruleRemoveById=930130,\
  ctl:ruleRemoveById=932250"

# Allow HTML comments used by Gutenberg (e.g., <!-- wp:paragraph -->)
SecRule REQUEST_BODY "@rx <!--\s?wp:" "id:1001003,phase:2,pass,nolog,noauditlog,ctl:auditEngine=Off,ctl:ruleRemoveById=941180"

# Optional: Additional CRS rules often triggered by WordPress activity (expand as needed)
SecRuleRemoveById 950901
SecRuleRemoveById 953100
SecRuleRemoveById 958030
SecRuleRemoveById 958057
SecRuleRemoveById 960015
SecRuleRemoveById 973300
SecRuleRemoveById 973333
SecRuleRemoveById 973335
SecRuleRemoveById 973337
SecRuleRemoveById 973340
SecRuleRemoveById 973343
SecRuleRemoveById 981173
SecRuleRemoveById 981176
SecRuleRemoveById 981204
SecRuleRemoveById 981240
SecRuleRemoveById 981243
SecRuleRemoveById 981245
SecRuleRemoveById 981246
SecRuleRemoveById 981248
SecRuleRemoveById 981257

Diese Ausnahmen entfernen nur gezielt problematische Regeln in /wp-admin/ und /wp-json/, ohne die gesamte WAF abzuschalten.

2. Datei in NGINX einbinden

Öffne die passende Serverkonfiguration deiner WordPress-Website (z. B. /etc/nginx/sites-enabled/example.com.conf) und ergänze im HTTPS-Block den ModSecurity-Block wie folgt:

example.com.conf excerpt
modsecurity on;
modsecurity_rules_file /etc/nginx/modsec/modsecurity.conf;
modsecurity_rules_file /etc/nginx/modsec/wp-admin-exceptions.conf;

3. Kondiguration testen und NGINX neu laden

Mit nachfolgendem Befehl testest du die Konfiguration von NGINX und startest bei Erfolg den Webserver neu.

Bash
sudo nginx -t && sudo systemctl reload nginx

Ergebnis

Mit dieser Konfiguration schützt ModSecurity deine WordPress-Seite zuverlässig mit dem OWASP Core Rule Set – ohne den Admin-Bereich oder die REST-API zu blockieren. Gleichzeitig vermeidest du die Deaktivierung ganzer Regelgruppen und behältst volle Kontrolle über sicherheitskritische Prüfungen.

Kommentare

Schreibe einen Kommentar