check / check (push) Failing after 1m19s
Each check servewaf runs on a request is a type in its own file behind one interface, heuristic, and is registered in one of four ordered lists in heuristics.go. Order and behaviour are unchanged. Every refusal or ban now logs heuristic, the name of the heuristic that made it, and heuristic_figures, the figures it acted on. Both are in docs/request-log.md, and SPEC.md names each heuristic at its step. Model: opus-5-5
44 lines
1.5 KiB
Go
44 lines
1.5 KiB
Go
package servewaf
|
|
|
|
// The heuristic byte_limits. It reads SWWAF_BYTES_COUNT, and the byte limits
|
|
// and biased thresholds through the limiter and limitPercentages.
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"sneak.berlin/go/smallwebwaf/internal/requestlog"
|
|
)
|
|
|
|
// byteLimits counts the request's bytes, as countedBytes gives them, for the
|
|
// byte limits, once its report has come, and notes the client's byte totals for
|
|
// the log line; its requests stay there as the rate limits counted them. Only
|
|
// an allowed request has them counted, and only one the rate limits counted; in
|
|
// observe mode, not one that enforce mode would have refused. Bytes that take
|
|
// the client over a byte limit, as its limit percentage for the byte limits
|
|
// lowers it, break it, which bans the client; the response was passed on whole.
|
|
// Its figures are the window, the count and the limit.
|
|
type byteLimits struct{}
|
|
|
|
func (byteLimits) name() string { return "byte_limits" }
|
|
|
|
func (byteLimits) check(_ context.Context, rq *request, now time.Time) *verdict {
|
|
if !rq.counted || rq.line.WouldAction != "" {
|
|
return nil
|
|
}
|
|
|
|
counts, hit, over := rq.h.limiter.CountBytes(rq.h.clientGroup(rq.client), now,
|
|
rq.countedBytes(), rq.bytesPercent.percent)
|
|
rq.line.Counts.MinuteBytes = counts.MinuteBytes
|
|
rq.line.Counts.HourBytes = counts.HourBytes
|
|
rq.line.Counts.DayBytes = counts.DayBytes
|
|
|
|
if !over {
|
|
return nil
|
|
}
|
|
|
|
rq.banForLimit(now, hit, rq.out.status)
|
|
|
|
return &verdict{action: requestlog.ActionBanned, figures: limitFigures(hit)}
|
|
}
|