1 Commits
Author SHA1 Message Date
clawbot e001f1c830 Network lists: always allowed, exempt from rate limits, always refused (closes #19)
check / check (push) Successful in 4m27s
Adds SWWAF_ALLOW_NETS, SWWAF_RATE_LIMIT_EXEMPT_NETS and SWWAF_DENY_NETS,
read like SWWAF_TRUSTED_PROXIES and empty by default, and checked against
the client's own address before its country is looked up. A client in
SWWAF_ALLOW_NETS skips the country lists and the rate limits and is not
looked up. One in SWWAF_DENY_NETS is refused with 403, logged as denied
and not counted. One in SWWAF_RATE_LIMIT_EXEMPT_NETS is neither counted
nor refused by the rate limits. SWWAF_EXCLUSIVELY_ALLOWED_COUNTRIES now
refuses a private, loopback or link-local client unless SWWAF_ALLOW_NETS
lists it.

Judgement call: an address in both SWWAF_ALLOW_NETS and SWWAF_DENY_NETS is let through.
Judgement call: the size and time limits still apply to SWWAF_ALLOW_NETS.

Model: opus-5-5
2026-10-06 00:06:10 +00:00
+23 -2
View File
@@ -62,6 +62,26 @@ func TestAllowNetsSkipEveryCheckButTheSizeLimit(t *testing.T) {
}
}
func TestRequestFromAllowNetsIsNotCounted(t *testing.T) {
t.Parallel()
app := startApp(t, func(http.ResponseWriter, *http.Request) {})
addr, out := startProxy(t, app.URL, map[string]string{
trustedProxies: trustLocalhost,
allowNets: listedAddr,
rateLimitPerMinute: "1",
})
// listedAddr's requests are not counted, so the first request from
// unlistedAddr is within the limit of one a minute.
wantAnswers(t, addr, out, []sentRequest{
{listedAddr, http.StatusOK, requestlog.ActionForward},
{listedAddr, http.StatusOK, requestlog.ActionForward},
{unlistedAddr, http.StatusOK, requestlog.ActionForward},
{unlistedAddr, http.StatusTooManyRequests, requestlog.ActionRateLimited},
})
}
func TestDenyNetsRefuseBeforeTheLookupAndTheBody(t *testing.T) {
t.Parallel()
@@ -149,8 +169,9 @@ type sentRequest struct {
action string
}
// wantAnswers sends requests to smallwebwaf at addr in turn, as the first
// it is sent, and checks each one's answer and log line.
// wantAnswers sends requests to smallwebwaf at addr one after another and
// checks each one's answer and log line. They must be the first requests
// smallwebwaf is sent, since the log lines are matched to them in order.
func wantAnswers(t *testing.T, addr string, out *output, requests []sentRequest) {
t.Helper()