selfhostedops-stack/crowdsec/appsec-rules/crs-route-exclusions.yaml
Maximilian Grimm 22300d7a28 Episode 13: correct the CRS exclusion mechanism (ruleRemoveById, not ruleEngine)
Follow-up measurements showed the first exclusion approach was too broad.
ctl:ruleEngine=Off disables the whole Coraza engine for the route, which also
turns off the native virtual-patching rules: a .env probe on such a route
returned 404 (no WAF) instead of 403.

The exclusion now uses ctl:ruleRemoveById=949110,959100 (the CRS inbound and
outbound anomaly-score blockers) so the engine stays on and virtual patching
keeps firing on the excluded routes. Measured: .env / PHPUnit / .git/config
still 403 on those routes, generic SQLi/XSS pass, non-excluded hosts keep full
CRS (27 of 41). Rule order relative to the CRS rule no longer matters.

Also measured and documented: RemoveInBandRuleByName in a pre_eval hook does
nothing to CRS (SQLi stayed 403 globally and per route); a full authenticated
Vaultwarden flow (register, login, sync, cipher create) passes under full CRS
on the vault host. README traps and numbers updated accordingly.
2026-09-16 21:06:32 +02:00

28 lines
1.8 KiB
YAML

name: selfhostedops/crs-route-exclusions
# ep13: entfernt je legitimer Route NUR die CRS-Anomalie-Blockregeln (949110
# inbound, 959100 outbound), sodass das generische CRS dort nicht mehr sperrt.
# Die Coraza-Engine bleibt an (ruleEngine On), deshalb laufen die nativen
# CrowdSec-vpatch-Regeln auf diesen Routen weiter (bekannte CVEs bleiben
# geschuetzt). NICHT ctl:ruleEngine=Off benutzen, das schaltet auch vpatch ab.
# Die Regel muss VOR crowdsecurity/crs stehen (Phase 1).
seclang_rules:
# Forgejo git smart-HTTP (clone/push), binaerer Pack-Body
- |
SecRule REQUEST_HEADERS:Host "@beginsWith git." "id:900101,phase:1,pass,nolog,chain,msg:'ep13 crs-off git smart-http'"
SecRule REQUEST_URI "@rx (git-upload-pack|git-receive-pack|/info/refs\?service=)" "ctl:ruleRemoveById=949110,ctl:ruleRemoveById=959100"
# Forgejo REST-API: Issues, Datei-Inhalte
- |
SecRule REQUEST_HEADERS:Host "@beginsWith git." "id:900102,phase:1,pass,nolog,chain,msg:'ep13 crs-off forgejo api'"
SecRule REQUEST_URI "@beginsWith /api/v1/" "ctl:ruleRemoveById=949110,ctl:ruleRemoveById=959100"
# Outline Dokument-API
- |
SecRule REQUEST_HEADERS:Host "@beginsWith wiki." "id:900103,phase:1,pass,nolog,chain,msg:'ep13 crs-off outline api'"
SecRule REQUEST_URI "@beginsWith /api/" "ctl:ruleRemoveById=949110,ctl:ruleRemoveById=959100"
# ntfy Publish (POST /<topic>)
- |
SecRule REQUEST_HEADERS:Host "@beginsWith ntfy." "id:900104,phase:1,pass,nolog,chain,msg:'ep13 crs-off ntfy publish'"
SecRule REQUEST_METHOD "@streq POST" "ctl:ruleRemoveById=949110,ctl:ruleRemoveById=959100"
# n8n Webhook-Pfade
- |
SecRule REQUEST_HEADERS:Host "@beginsWith n8n." "id:900105,phase:1,pass,nolog,chain,msg:'ep13 crs-off n8n webhook'"
SecRule REQUEST_URI "@beginsWith /webhook" "ctl:ruleRemoveById=949110,ctl:ruleRemoveById=959100"