Rule files, and bans for a clear sign of attack (closes #24)
check / check (push) Successful in 2m58s
check / check (push) Successful in 2m58s
Every *.rules file in SWWAF_RULES_DIR not named with a leading dot is read at start, and again 2 seconds after the directory's last change. Each request is checked against the rules after the rate limits: log notes a match, block refuses with 403, ban refuses and bans the netblock for SWWAF_ATTACK_BAN_DURATION, made permanent by its next request or attack. path, query and uri are matched as the request line sent them; header:Host and header:Transfer-Encoding are refused. Bans gain a cause. The image ships 00-default.rules. Judgement call: a header sent twice is matched with its values joined by ", ". Judgement call: SWWAF_MAX_BAN_DURATION does not cap a ban for an attack. Not in this unit: offences for rule matches, with the error burst. Model: opus-5-5
This commit is contained in:
@@ -278,6 +278,7 @@ func TestBanNotes(t *testing.T) {
|
||||
Netblock: netblock,
|
||||
Start: start,
|
||||
Expires: start.Add(time.Hour),
|
||||
Cause: bans.CauseLimit,
|
||||
Notes: bans.Notes{
|
||||
Country: "DE",
|
||||
Limit: 1,
|
||||
@@ -295,7 +296,7 @@ func TestBanNotes(t *testing.T) {
|
||||
// refused under the ban.
|
||||
Requests: 4,
|
||||
Refused: 2,
|
||||
EarlierBans: 0,
|
||||
EarlierBans: bans.EarlierBans{},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -312,8 +313,8 @@ func TestBanNotes(t *testing.T) {
|
||||
s.get(fromDE, http.StatusForbidden, requestlog.ActionRateLimited)
|
||||
|
||||
got = ledger.Bans(netblock)
|
||||
if len(got) != 2 || got[1].Notes.EarlierBans != 1 {
|
||||
t.Errorf("bans %+v, want two, the second with one earlier ban", got)
|
||||
if len(got) != 2 || got[1].Notes.EarlierBans != (bans.EarlierBans{Limit: 1}) {
|
||||
t.Errorf("bans %+v, want two, the second with one earlier ban for a limit", got)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user