Twenty login tries before the backoff starts, not five
A guest password is typed by hand off a message on a phone. Five tries is not many when a hyphen lands in the wrong place, and being told to wait is worse than the brute-force risk here: past twenty the doubling lockout still applies, the global backstop is unchanged, and the password is ~78 bits. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
ed64aca63b
commit
a0987c940f
@@ -318,11 +318,10 @@ func (s *Sessions) RevokeOthers(user, keep string) int {
|
||||
// RevokeUser ends every session of user (the account is going away).
|
||||
func (s *Sessions) RevokeUser(user string) { s.RevokeOthers(user, "") }
|
||||
|
||||
// Limiter is a single global backoff: after 5 failures, each further failure
|
||||
// doubles a lockout starting at 30s, capped at 10 minutes. Single-user box.
|
||||
// Limiter locks out a client after repeated failed logins, per client address, with a
|
||||
// global backstop so a botnet can't burn CPU on argon2 indefinitely. A lockout for one
|
||||
// address never blocks another.
|
||||
// address never blocks another. Past perClientLock failures, each further failure doubles a
|
||||
// lockout starting at 30s, capped at 10 minutes.
|
||||
type Limiter struct {
|
||||
mu sync.Mutex
|
||||
clients map[string]*bucket
|
||||
@@ -338,7 +337,11 @@ type bucket struct {
|
||||
var ErrLocked = errors.New("too many failed logins")
|
||||
|
||||
const (
|
||||
perClientLock = 5 // failures before a client is locked
|
||||
// perClientLock is how many failures one address gets before it is made to wait. Set high
|
||||
// on purpose: a guest login is a generated password read off a message and typed by hand
|
||||
// on a phone, and being locked out for fumbling it is worse than the brute-force risk —
|
||||
// which the doubling backoff past this point, and the global backstop, still cover.
|
||||
perClientLock = 20
|
||||
globalLock = 100 // failures (all clients) in the window before everyone waits a minute
|
||||
globalWindow = 5 * time.Minute
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user