A ban for a limit broken again within SWWAF_LIMIT_BAN_REPEAT_WINDOW lasts three times the netblock's last limit or admin ban, measured as its expires less its start. An entry written by hand into bans.json with an expires at or before its start made that length zero or less, so the netblock's next limit ban ended as it was made and refused nothing.
The bans.json checks (internal/state/state.go, bansFile.check) now refuse such an entry, naming its place in the file, as they refuse the other malformed entries. At start it stops the start. An edit made while running is set aside as bans.json.bad, because edits go through the same check. A permanent ban, whose expires is null, is not affected. The README.md "State files" lists of what stops the start and what is set aside now name it. SPEC.md lists no single entry checks, so it is unchanged.
Every ban smallwebwaf makes itself ends after its start (the ban endpoint takes only durations above zero, and a CrowdSec ban is made only while its decision is in force), so it never writes a file it would refuse.
Deviation from the plan: an expires equal to its start is refused too, not only one earlier, because it causes the same defect (the next limit ban is three times zero long).
The test covers refusal at start only. The while-running path shares the check and is not tested separately.
Model: opus-5-5
A ban for a limit broken again within `SWWAF_LIMIT_BAN_REPEAT_WINDOW` lasts three times the netblock's last `limit` or `admin` ban, measured as its `expires` less its `start`. An entry written by hand into `bans.json` with an `expires` at or before its `start` made that length zero or less, so the netblock's next limit ban ended as it was made and refused nothing.
The `bans.json` checks (`internal/state/state.go`, `bansFile.check`) now refuse such an entry, naming its place in the file, as they refuse the other malformed entries. At start it stops the start. An edit made while running is set aside as `bans.json.bad`, because edits go through the same check. A permanent ban, whose `expires` is `null`, is not affected. The `README.md` "State files" lists of what stops the start and what is set aside now name it. `SPEC.md` lists no single entry checks, so it is unchanged.
Every ban `smallwebwaf` makes itself ends after its start (the ban endpoint takes only durations above zero, and a CrowdSec ban is made only while its decision is in force), so it never writes a file it would refuse.
Deviation from the plan: an `expires` equal to its `start` is refused too, not only one earlier, because it causes the same defect (the next limit ban is three times zero long).
The test covers refusal at start only. The while-running path shares the check and is not tested separately.
Model: opus-5-5
A netblock's next ban for a broken limit within
SWWAF_LIMIT_BAN_REPEAT_WINDOW lasts three times its last limit or admin
ban. A hand-written entry with an expires at or before its start made
that length zero or less, so the next limit ban refused nothing. The
bans.json checks now refuse such an entry: it stops the start, and an
edit holding one is set aside as bans.json.bad while running. README's
"State files" lists it with the other refused entries.
Model: opus-5-5
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.
A ban for a limit broken again within
SWWAF_LIMIT_BAN_REPEAT_WINDOWlasts three times the netblock's lastlimitoradminban, measured as itsexpiresless itsstart. An entry written by hand intobans.jsonwith anexpiresat or before itsstartmade that length zero or less, so the netblock's next limit ban ended as it was made and refused nothing.The
bans.jsonchecks (internal/state/state.go,bansFile.check) now refuse such an entry, naming its place in the file, as they refuse the other malformed entries. At start it stops the start. An edit made while running is set aside asbans.json.bad, because edits go through the same check. A permanent ban, whoseexpiresisnull, is not affected. TheREADME.md"State files" lists of what stops the start and what is set aside now name it.SPEC.mdlists no single entry checks, so it is unchanged.Every ban
smallwebwafmakes itself ends after its start (the ban endpoint takes only durations above zero, and a CrowdSec ban is made only while its decision is in force), so it never writes a file it would refuse.Deviation from the plan: an
expiresequal to itsstartis refused too, not only one earlier, because it causes the same defect (the next limit ban is three times zero long).The test covers refusal at start only. The while-running path shares the check and is not tested separately.
Model: opus-5-5
PASS
Model: opus-5-5