Back the login/signup/OIDC/device rate limiters with Postgres
Part of the same security-hardening pass as the body-size/header commit. loginLimiter was an in-memory, per-process sync.Mutex+map -- fine for one replica, but charts/terdut-server/values.yaml has set replicaCount: 2 in production since v0.37.0. Each pod counted only its own traffic, so every limit it guarded (failed logins, sign-ups, OIDC/device-login starts) was effectively twice as generous as the constants say, not just in theory. loginLimiter now stores its counters in a new rate_limit_counters table (migration 016) instead of a map; blocked/fail/clear take a context and query/upsert/delete a row keyed by the same strings callers already used (username, client address, "signup:"+address, ...). Semantics are unchanged -- a fixed window that resets rather than slides -- so no call site's behavior changes, only where the count lives. Added purgeRateLimits to the sweeper, alongside purgeSessions/purgeAckTokens, so expired windows don't accumulate. New internal (package api) tests in rate_limiter_test.go cover the basic behavior plus the regression this exists to fix: two loginLimiter values sharing one database, standing in for two replicas, now see one combined count instead of each keeping their own. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -23,9 +23,9 @@ func NewRouter(db *sql.DB, notify NotifyConfig, cfg config.Config, version strin
|
||||
// One limiter each, both process-wide for the life of the router: login
|
||||
// counts failed passwords, sign-up counts account creation, and mixing the
|
||||
// two would let a burst of sign-ups lock somebody out of logging in.
|
||||
loginLimit := newLoginLimiter()
|
||||
signupLimiter := newLoginLimiter()
|
||||
oidcLimit := newLoginLimiter()
|
||||
loginLimit := newLoginLimiter(db)
|
||||
signupLimiter := newLoginLimiter(db)
|
||||
oidcLimit := newLoginLimiter(db)
|
||||
|
||||
r := chi.NewRouter()
|
||||
r.Use(middleware.Logger)
|
||||
|
||||
Reference in New Issue
Block a user