discriminator: the header limits are the first check (closes #311)
check / check (push) Successful in 3m24s

A request over 50 cookies or 100 header fields is now refused before any
other check. It causes no lookup, no query to RouteWatch, a DNS blocklist
or AbuseIPDB, no rule file match and no Core Rule Set. The rate limits no
longer count it, and a banned or denied client gets 431 for it. In observe
mode no lookup is made for it. Requests within the limits go through the
same checks in the same order.

Model: opus-5-5
This commit is contained in:
sneak committed 2026-11-11 00:26:14 +00:00
1 parent ad36dd1775
commit f519e2ca9e
6 files changed
+148 -75

No files matched your search

+6 -12
View File
@@ -10,22 +10,23 @@ import (
"sneak.berlin/go/smallwebwaf/internal/requestlog"
)
// The header limits: the most cookies and header fields a request may have
// when the checks reach the Core Rule Set. Real clients never reach them.
// The header limits: the most cookies and header fields a request may have.
// Real clients never reach them.
const (
maxCookies = 50
maxHeaderFields = 100
)
// headerLimits refuses a request over the header limits, with 431. Its figures
// are the request's header fields and cookies, and the limit of each.
// headerLimits refuses a request with more than maxHeaderFields header fields
// or more than maxCookies cookies, with 431. Its figures are the request's
// header fields and cookies, and the limit of each.
type headerLimits struct{}
func (headerLimits) name() string { return "header_limits" }
func (headerLimits) check(_ context.Context, rq *request, _ time.Time) *verdict {
fields, cookies := rq.headerCounts()
if !overHeaderLimits(fields, cookies) {
if fields <= maxHeaderFields && cookies <= maxCookies {
return nil
}
@@ -38,13 +39,6 @@ func (headerLimits) check(_ context.Context, rq *request, _ time.Time) *verdict
}
}
// overHeaderLimits reports whether a request with these counts of header fields
// and cookies, as headerCounts counts them, is over the header limits: it has
// more than maxHeaderFields fields or more than maxCookies cookies.
func overHeaderLimits(fields, cookies int) bool {
return fields > maxHeaderFields || cookies > maxCookies
}
// headerCounts returns the request's header fields, each value of a header sent
// twice being one, and its cookies, each part of a Cookie header between
// semicolons being one unless it is empty or only spaces and tabs. The Core