package servewaf // The heuristic trap_paths. It reads SWWAF_TRAP_PATHS. import ( "context" "slices" "time" "sneak.berlin/go/smallwebwaf/internal/bans" "sneak.berlin/go/smallwebwaf/internal/requestlog" "sneak.berlin/go/smallwebwaf/internal/rules" ) // trapPaths refuses a request for a path in SWWAF_TRAP_PATHS: its path as a // path rule sees it, without the query, as sent or once percent-decoded, is one // of them. Such a request is a clear sign of attack, as a ban rule's match is: // it bans the client's netblock, or in observe mode raises the alert for the // ban it would have made. The ban's notes give the path as sent, and so does // its figure. type trapPaths struct{} func (trapPaths) name() string { return "trap_paths" } func (trapPaths) check(_ context.Context, rq *request, now time.Time) *verdict { path := rules.Path(rq.in) if !slices.Contains(rq.h.config.TrapPaths, path) && !slices.Contains(rq.h.config.TrapPaths, rules.DecodeOnce(path)) { return nil } rq.attack = true rq.banForAttack(now, bans.Notes{TrapPath: path}) return &verdict{ action: requestlog.ActionBanned, figures: map[string]any{"path": path}, } }