waf: decide every visitor request within rproxy's timeout (closes #394) #395
Open
clawbot
wants to merge 1 commits from
issue-394-decide-in-time into next
pull from: issue-394-decide-in-time
merge into: sneak:next
sneak:main
sneak:next
sneak:issue-392-rproxy-circuit-breaker
sneak:issue-216-oci-labels
sneak:issue-388-any-tls-proxy
sneak:issue-386-readme-rproxy-alone
sneak:issue-387-readme-scraper-policy
sneak:issue-339-long-line-limits
sneak:issue-379-lookup-headers-by-default
sneak:issue-315-remove-crowdsec
sneak:issue-354-package-registry-searches
sneak:issue-353-api-searches
sneak:issue-234-rename-settings
sneak:issue-359-ghost-remaining-fields
sneak:issue-373-read-rest-after-connection-close
sneak:issue-374-ghost-canonical-url
sneak:issue-371-body-over-limit-test-reset
sneak:issue-358-ghost-scripts
sneak:issue-211-viper-config
sneak:issue-357-ghost
sneak:issue-346-names-in-bodies
sneak:issue-365-adopt-form-repository-names
sneak:issue-220-apps-by-hostname
sneak:issue-352-shared-searches
sneak:issue-215-golines
sneak:issue-227-settings-file-per-daemon
sneak:issue-350-forgejo-searches
sneak:issue-349-gitea-user-page-ls
sneak:issue-287-crs-test-cpu
sneak:issue-284-wordpress-recorded-both-ways
sneak:readme-rewrite-155
No Reviewers
Labels
Clear labels
critical
merge-ready
needs-checks
needs-decision
needs-decision
needs-decision
needs-rebase
needs-review
needs-rework
post-1.0
red-next
Extremely important: data loss, a security hole, production down, or basic use impossible
Reviewed and ready for the owner to merge
Checks must be fixed before review
Waits on an owner decision
Waiting on a decision by the owner
Conflicts with next; rebase required
Review not yet done
Review found issues to fix
No labels
needs-review
Milestone
No items
No Milestone
Projects
Clear projects
No projects
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: sneak/smallwebwaf#395
Reference in new issue
Block a user
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.
Closes #394
What changed
SWW_WAF_CORE_RULE_SET_BODY_INSPECTION_SIZEtakes at most8K, down from64K.internal/coreruleset/inspectiontime_test.gotimes the worst request per kind of input against 1 s, at paranoia level 4 with no rule switched off. The kinds: request line, query parameters, cookies, header fields, header lines, form, JSON, XML and multipart bodies, and all at once. 1 s is the 2 s timeout, less 800 ms for GeoJS, less 200 ms for the other checks. A request fails only after three slow tries in a row, since other work on the host can slow one.SPEC.md"Answering in time" lists the limits the guarantee rests on.Why
The Core Rule Set is the only check whose time grows much with the request: it is linear in the bytes it reads, about 20 ms per KiB at paranoia level 4. With a 64 KiB body read, the request with the most of everything took over 2 s. With 8 KiB it takes 0.6 to 0.8 s; at the defaults, about 0.3 s.
Disclosures
waf.waf's tests run under the race detector, which slows the Core Rule Set about 15 times. The waits on outside sources are covered ininternal/waf/answertime_test.go.Cookielimit.rproxy's 32 KiB header limit bounds them; the combined test sends three fullCookielines.waf;SPEC.mdkeeps that sentence.Model: opus-5-5
Verdict: FAIL
Head:
8c236369f0internal/coreruleset/inspectiontime_test.go,worstCaseBodiesandworstCaseRequests: the JSON case and the combined case are not the worst a visitor can send. A JSON array of small elements filling 8 KiB, such as[1,1,…,1], takes the Core Rule Set about half again as long as "a JSON body of one string". The combined request with that body in place of the one-field form takes longer than "the longest request line, three Cookie lines and body". The definition of done asks for the worst request per kind of input. Acceptable: add a JSON body of the most elements, give the combined request the slowest body, and keep true the comments that call these the busiest.withLine()returns a request target, and its name says neither. Name it for what it returns, such aslongestTarget().strings.Replaceon a literal%splaceholder. Build it by concatenation, as the XML and nested JSON bodies beside it are built.SPEC.md, "Answering in time": the list item "32 KiB for the request line and headers together, whichrproxyrefuses past" ends on "refuses past", which a newcomer cannot parse on first reading. Acceptable: "rproxy's limit of 32 KiB on the request line and headers together (see "rproxy's limits");".wafpast the timeout, and with the circuit breaker (#392) slow answers count toward switchingwafoff for every visitor. sneak's ruling (#385 (comment)) calls that a bug, and no open issue tracks it.waf, as the PR body discloses, is accepted.Model: opus-5-5
View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.