fix(waf): promote 920440 chain-safely, not on its chain starter (round 2)
Owner decision. `SecRuleUpdateActionById 920440 "ctl:ruleEngine=On"` ran on
920440's chain STARTER (`REQUEST_BASENAME "@rx \.([^.]+)$"`), which matches
every URL with a file extension, so every *.php/*.css request was evaluated
with the engine On: full CRS anomaly enforcement (949110) and 200002, in
detect_only mode too.
Replaced by `SecRule TX:EXTENSION "@within %{tx.restricted_extensions}"
... ctl:ruleEngine=On` (id 992920440, phase 1, after 920440). CRS 4.25.0
sets tx.extension in 920440's first link (REQUEST-920...conf:667, the
coreruleset version coraza-spoa v0.7.1 pins). Live, both modes:
.bak/.sql/.save/.old/.swp probes still 403; benign .php/.css 200; a
942100 SQLi on /x.php and the onclick / "select ... union" admin saves are
no longer 403 in detect_only.
test-waf-body-inspection.py: 19 tests (2 new, repo-checkout only).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
cc0652e0c0
commit
234029c249
2 files changed
+48
-10
No files matched your search
+19
-10
@@ -59,17 +59,26 @@ SecRuleUpdateActionById 944100-944300 "ctl:ruleEngine=On"
|
||||
# single GCP-hosted scanner. Zero false positives observed; standard
|
||||
# WP/WooCommerce/Divi/HPR URLs do not end in these extensions.
|
||||
# ---------------------------------------------------------------------------
|
||||
# WARNING (measured 2026-10-09, Coraza v3.7.0 + CRS 4.25.0, in-process AND
|
||||
# live behind haproxy): 920440 is a CHAIN whose first link is
|
||||
# HOW IT IS PROMOTED (changed 2026-10-09, haproxy-manager-base 2026.10.2).
|
||||
# This used to be `SecRuleUpdateActionById 920440 "ctl:ruleEngine=On"`, which
|
||||
# was WRONG: 920440 is a CHAIN whose first link is
|
||||
# `REQUEST_BASENAME "@rx \.([^.]+)$"` -- it matches EVERY URL with a file
|
||||
# extension. Coraza runs the appended ctl:ruleEngine=On when that first link
|
||||
# matches, even though the chain then fails. So on any *.php / *.css / ...
|
||||
# request the engine is On for the rest of the transaction: 949110 enforces
|
||||
# the whole CRS anomaly score (a 942100 SQLi GET is 403 on /x.php, 200 on /x)
|
||||
# and 200002 denies body-parse errors -- in detect_only mode too, because
|
||||
# SecRuleEngine DetectionOnly cannot override a runtime ctl. Not changed here
|
||||
# (it would loosen live blocking fleet-wide); see waf-body-hardening-report.md.
|
||||
SecRuleUpdateActionById 920440 "ctl:ruleEngine=On"
|
||||
# extension -- and Coraza runs actions appended to a chain starter when that
|
||||
# first link matches, even though the chain then fails. Measured (Coraza
|
||||
# v3.7.0 + CRS 4.25.0, in-process and live): every *.php / *.css / ...
|
||||
# request ran with the engine On, so the whole CRS anomaly score (949110) and
|
||||
# 200002 enforced there -- in detect_only mode too, since SecRuleEngine
|
||||
# DetectionOnly cannot override a runtime ctl.
|
||||
#
|
||||
# Now: 920440 itself is untouched (it still sets tx.extension in its first
|
||||
# link and adds the anomaly score in its second), and this separate phase-1
|
||||
# rule, which runs after it, flips the engine only when the extension really
|
||||
# is in tx.restricted_extensions -- the original intent. Removing 920440
|
||||
# (break-glass, a per-host exception) also removes tx.extension, so this rule
|
||||
# goes quiet with it. Id 992920440 is outside WHP's generated range
|
||||
# (990000000-991999999).
|
||||
SecRule TX:EXTENSION "@within %{tx.restricted_extensions}" \
|
||||
"id:992920440,phase:1,pass,nolog,t:none,t:lowercase,ctl:ruleEngine=On"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 930130 — Restricted File Access Attempt
|
||||
|
||||
Reference in new issue
Block a user