sneak, on #385 (comment): "If a visitor can perform a denial of service attack on the server, that's a bug in the server. We need to make sure that any requests that a visitor sends can be decided within the timeout. If they cannot, that is a bug in the decider."
Reworded: every request a visitor can send must get a decision from waf within rproxy's backend timeout (SWW_RPROXY_WAF_BACKEND_TIMEOUT_MS). A request that takes waf longer is a bug in waf, and is fixed in waf.
Work
Find every step of waf's decision whose time grows with what the visitor sends: body size, header count and size, URL and query length, cookie count, rule evaluation on crafted input.
For each, either bound it so the decision stays well within the timeout, or show that it already is.
Fix any path that can exceed the timeout. Prefer a fixed limit with a clear decision (for example deny an oversized part) over new settings.
Definition of done
A test per input dimension above sends a worst-case request a visitor could send, and asserts waf decides it within the default timeout, with a margin. Tests stay light: no large data held in memory, inputs streamed.
Every path found that could exceed the timeout is fixed in this PR; SPEC.md states the limits that make the guarantee hold.
No new settings unless a limit cannot be a fixed constant.
make check passes.
If the work turns out larger than one PR, label the issue not-one-pr and stop.
Model: opus-5-5
sneak, on https://git.eeqj.de/sneak/smallwebwaf/issues/385#issuecomment-181334: "If a visitor can perform a denial of service attack on the server, that's a bug in the server. We need to make sure that any requests that a visitor sends can be decided within the timeout. If they cannot, that is a bug in the decider."
Reworded: every request a visitor can send must get a decision from `waf` within `rproxy`'s backend timeout (`SWW_RPROXY_WAF_BACKEND_TIMEOUT_MS`). A request that takes `waf` longer is a bug in `waf`, and is fixed in `waf`.
## Work
- Find every step of `waf`'s decision whose time grows with what the visitor sends: body size, header count and size, URL and query length, cookie count, rule evaluation on crafted input.
- For each, either bound it so the decision stays well within the timeout, or show that it already is.
- Fix any path that can exceed the timeout. Prefer a fixed limit with a clear decision (for example deny an oversized part) over new settings.
## Definition of done
- A test per input dimension above sends a worst-case request a visitor could send, and asserts `waf` decides it within the default timeout, with a margin. Tests stay light: no large data held in memory, inputs streamed.
- Every path found that could exceed the timeout is fixed in this PR; `SPEC.md` states the limits that make the guarantee hold.
- No new settings unless a limit cannot be a fixed constant.
- `make check` passes.
If the work turns out larger than one PR, label the issue `not-one-pr` and stop.
Model: opus-5-5
Only the Core Rule Set's time grows much with what a visitor sends. At paranoia level 4 with a 64 KiB body read, one request within every limit took over 2 s. SWW_WAF_CORE_RULE_SET_BODY_INSPECTION_SIZE now takes at most 8K, which brings that request under 1 s. The new tests time the worst request for each kind of input against 1 s.
Deviation: the tests time the Core Rule Set rather than all of waf, because waf's tests run under the race detector.
Not in this issue: many such requests at once can still overload waf.
Model: opus-5-5
PR: https://git.eeqj.de/sneak/smallwebwaf/pulls/395, branch `issue-394-decide-in-time`.
Only the Core Rule Set's time grows much with what a visitor sends. At paranoia level 4 with a 64 KiB body read, one request within every limit took over 2 s. `SWW_WAF_CORE_RULE_SET_BODY_INSPECTION_SIZE` now takes at most `8K`, which brings that request under 1 s. The new tests time the worst request for each kind of input against 1 s.
- Deviation: the tests time the Core Rule Set rather than all of `waf`, because `waf`'s tests run under the race detector.
- Not in this issue: many such requests at once can still overload `waf`.
Model: opus-5-5
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
sneak, on #385 (comment): "If a visitor can perform a denial of service attack on the server, that's a bug in the server. We need to make sure that any requests that a visitor sends can be decided within the timeout. If they cannot, that is a bug in the decider."
Reworded: every request a visitor can send must get a decision from
wafwithinrproxy's backend timeout (SWW_RPROXY_WAF_BACKEND_TIMEOUT_MS). A request that takeswaflonger is a bug inwaf, and is fixed inwaf.Work
waf's decision whose time grows with what the visitor sends: body size, header count and size, URL and query length, cookie count, rule evaluation on crafted input.Definition of done
wafdecides it within the default timeout, with a margin. Tests stay light: no large data held in memory, inputs streamed.SPEC.mdstates the limits that make the guarantee hold.make checkpasses.If the work turns out larger than one PR, label the issue
not-one-prand stop.Model: opus-5-5
PR: #395, branch
issue-394-decide-in-time.Only the Core Rule Set's time grows much with what a visitor sends. At paranoia level 4 with a 64 KiB body read, one request within every limit took over 2 s.
SWW_WAF_CORE_RULE_SET_BODY_INSPECTION_SIZEnow takes at most8K, which brings that request under 1 s. The new tests time the worst request for each kind of input against 1 s.waf, becausewaf's tests run under the race detector.waf.Model: opus-5-5