Bans as sneak set them out in #2: seven days for a clear sign of attack and permanent on a repeat; an hour for a broken limit, longer on each repeat, permanent past seven days. Each ban carries the notes of #4, and the ban file can be edited while smallwebwaf runs, as the "Bans" and "Persistent state" sections of SPEC.md (#9) describe. Milestone 2 refuses a client while it is over a limit and bans no one (#14).
Not scheduled: it waits for sneak to put it in a milestone.
Model: opus-5-5
Bans as sneak set them out in https://git.eeqj.de/sneak/smallwebwaf/issues/2: seven days for a clear sign of attack and permanent on a repeat; an hour for a broken limit, longer on each repeat, permanent past seven days. Each ban carries the notes of https://git.eeqj.de/sneak/smallwebwaf/issues/4, and the ban file can be edited while smallwebwaf runs, as the "Bans" and "Persistent state" sections of `SPEC.md` (https://git.eeqj.de/sneak/smallwebwaf/pulls/9) describe. Milestone 2 refuses a client while it is over a limit and bans no one (https://git.eeqj.de/sneak/smallwebwaf/issues/14).
Not scheduled: it waits for sneak to put it in a milestone.
Model: opus-5-5
Plan. The build order in SPEC.md puts the bans that broken request limits lead to right after the static lists (#19), so they are built next, as "Bans" describes, in memory only. Writing them to bans.json and reading them at start come with the state files (#17); bans for a clear sign of attack come with the rule files.
A request over a request limit is refused with SWWAF_BAN_RESPONSE and bans the client's netblock (its IPv4 address, widened by SWWAF_BAN_SCOPE_V4_PREFIX, or its IPv6 group): SWWAF_LIMIT_BAN_DURATION for a first ban, three times the last one when the limit is broken again within SWWAF_LIMIT_BAN_REPEAT_WINDOW after it ended, and permanent once that would pass SWWAF_MAX_BAN_DURATION. Each such ban sets the client's counters back to zero. Its log line keeps actionrate_limited and limit_hit, and gains offence and ban_expires.
The ban ledger is checked after the static lists and before the lookup: a request from a banned netblock is refused with SWWAF_BAN_RESPONSE, logged with actionbanned and ban_expires, not counted against limits, and counted in the ban's notes.
At most SWWAF_MAX_BANS bans are held; when full, the one whose netblock has gone longest without a request is dropped first.
Each ban carries the notes "Persistent state" lists, as far as they are known at this stage: the limit, its window and the count reached; the AS number, AS name and country when looked up; the last ten requests that counted toward it, each text cut to 256 bytes; how many requests counted and over what time; the requests refused under it; earlier bans of each kind. The netblock's total since it was first seen comes with the client history in #17. Memory stays bounded; the PR body says what the notes cost at the default bounds.
SWWAF_BAN_RESPONSE (403, 429 or close) also answers the country lists and SWWAF_DENY_NETS, as "Data flow for one request" says.
New settings, each with its default from "Configuration surface": SWWAF_BAN_RESPONSE, SWWAF_LIMIT_BAN_DURATION, SWWAF_LIMIT_BAN_REPEAT_WINDOW, SWWAF_MAX_BAN_DURATION, SWWAF_MAX_BANS, SWWAF_BAN_SCOPE_V4_PREFIX; a value set but invalid stops the start. README.md documents them and the change from 429.
Definition of done: tests, on a clock the test controls, show a first ban, the threefold repeats, the permanent ban, the repeat window running out, counters reset by a ban, a banned netblock refused and not counted, the SWWAF_MAX_BANS bound dropping the right ban, SWWAF_BAN_SCOPE_V4_PREFIX, each SWWAF_BAN_RESPONSE value, the notes, the defaults and invalid values; make check green; one PR to next, passed by a reviewer who did not write it.
Model: opus-5-5
Plan. The build order in `SPEC.md` puts the bans that broken request limits lead to right after the static lists (https://git.eeqj.de/sneak/smallwebwaf/issues/19), so they are built next, as "Bans" describes, in memory only. Writing them to `bans.json` and reading them at start come with the state files (https://git.eeqj.de/sneak/smallwebwaf/issues/17); bans for a clear sign of attack come with the rule files.
- A request over a request limit is refused with `SWWAF_BAN_RESPONSE` and bans the client's netblock (its IPv4 address, widened by `SWWAF_BAN_SCOPE_V4_PREFIX`, or its IPv6 group): `SWWAF_LIMIT_BAN_DURATION` for a first ban, three times the last one when the limit is broken again within `SWWAF_LIMIT_BAN_REPEAT_WINDOW` after it ended, and permanent once that would pass `SWWAF_MAX_BAN_DURATION`. Each such ban sets the client's counters back to zero. Its log line keeps `action` `rate_limited` and `limit_hit`, and gains `offence` and `ban_expires`.
- The ban ledger is checked after the static lists and before the lookup: a request from a banned netblock is refused with `SWWAF_BAN_RESPONSE`, logged with `action` `banned` and `ban_expires`, not counted against limits, and counted in the ban's notes.
- At most `SWWAF_MAX_BANS` bans are held; when full, the one whose netblock has gone longest without a request is dropped first.
- Each ban carries the notes "Persistent state" lists, as far as they are known at this stage: the limit, its window and the count reached; the AS number, AS name and country when looked up; the last ten requests that counted toward it, each text cut to 256 bytes; how many requests counted and over what time; the requests refused under it; earlier bans of each kind. The netblock's total since it was first seen comes with the client history in https://git.eeqj.de/sneak/smallwebwaf/issues/17. Memory stays bounded; the PR body says what the notes cost at the default bounds.
- `SWWAF_BAN_RESPONSE` (`403`, `429` or `close`) also answers the country lists and `SWWAF_DENY_NETS`, as "Data flow for one request" says.
- New settings, each with its default from "Configuration surface": `SWWAF_BAN_RESPONSE`, `SWWAF_LIMIT_BAN_DURATION`, `SWWAF_LIMIT_BAN_REPEAT_WINDOW`, `SWWAF_MAX_BAN_DURATION`, `SWWAF_MAX_BANS`, `SWWAF_BAN_SCOPE_V4_PREFIX`; a value set but invalid stops the start. `README.md` documents them and the change from `429`.
Definition of done: tests, on a clock the test controls, show a first ban, the threefold repeats, the permanent ban, the repeat window running out, counters reset by a ban, a banned netblock refused and not counted, the `SWWAF_MAX_BANS` bound dropping the right ban, `SWWAF_BAN_SCOPE_V4_PREFIX`, each `SWWAF_BAN_RESPONSE` value, the notes, the defaults and invalid values; `make check` green; one PR to `next`, passed by a reviewer who did not write it.
Model: opus-5-5
clawbot
self-assigned this 2026-10-06 01:25:03 +02:00
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.
Bans as sneak set them out in #2: seven days for a clear sign of attack and permanent on a repeat; an hour for a broken limit, longer on each repeat, permanent past seven days. Each ban carries the notes of #4, and the ban file can be edited while smallwebwaf runs, as the "Bans" and "Persistent state" sections of
SPEC.md(#9) describe. Milestone 2 refuses a client while it is over a limit and bans no one (#14).Not scheduled: it waits for sneak to put it in a milestone.
Model: opus-5-5
Plan. The build order in
SPEC.mdputs the bans that broken request limits lead to right after the static lists (#19), so they are built next, as "Bans" describes, in memory only. Writing them tobans.jsonand reading them at start come with the state files (#17); bans for a clear sign of attack come with the rule files.SWWAF_BAN_RESPONSEand bans the client's netblock (its IPv4 address, widened bySWWAF_BAN_SCOPE_V4_PREFIX, or its IPv6 group):SWWAF_LIMIT_BAN_DURATIONfor a first ban, three times the last one when the limit is broken again withinSWWAF_LIMIT_BAN_REPEAT_WINDOWafter it ended, and permanent once that would passSWWAF_MAX_BAN_DURATION. Each such ban sets the client's counters back to zero. Its log line keepsactionrate_limitedandlimit_hit, and gainsoffenceandban_expires.SWWAF_BAN_RESPONSE, logged withactionbannedandban_expires, not counted against limits, and counted in the ban's notes.SWWAF_MAX_BANSbans are held; when full, the one whose netblock has gone longest without a request is dropped first.SWWAF_BAN_RESPONSE(403,429orclose) also answers the country lists andSWWAF_DENY_NETS, as "Data flow for one request" says.SWWAF_BAN_RESPONSE,SWWAF_LIMIT_BAN_DURATION,SWWAF_LIMIT_BAN_REPEAT_WINDOW,SWWAF_MAX_BAN_DURATION,SWWAF_MAX_BANS,SWWAF_BAN_SCOPE_V4_PREFIX; a value set but invalid stops the start.README.mddocuments them and the change from429.Definition of done: tests, on a clock the test controls, show a first ban, the threefold repeats, the permanent ban, the repeat window running out, counters reset by a ban, a banned netblock refused and not counted, the
SWWAF_MAX_BANSbound dropping the right ban,SWWAF_BAN_SCOPE_V4_PREFIX, eachSWWAF_BAN_RESPONSEvalue, the notes, the defaults and invalid values;make checkgreen; one PR tonext, passed by a reviewer who did not write it.Model: opus-5-5
Built in #69, waiting for review.
Model: opus-5-5
clawbot referenced this issue2026-10-06 05:29:22 +02:00