fix(auth): widen the per-IP login throttle to 50, keep the per-account lockout at 10

One AUTH_FAILURE_MAX (10 per 15 min) gated the single-user per-IP
bucket, the multi-user per-IP pre-gate, the per-username lockout and the
hook-secret bucket. Clients sharing one egress IP (NAT, a tunnel, an
automated client retrying) were throttled after 10 failures in total.

Add AUTH_IP_FAILURE_MAX = 50 and use it for the two per-IP login buckets
only. The per-username lockout and the hook-secret bucket keep
AUTH_FAILURE_MAX = 10, so guessing against any one account, or against
the hook secret, is no easier than before.
This commit is contained in:
Aamer Akhter committed 2026-10-22 17:23:03 -04:00
1 parent 002de32a08
commit ebb9e00de9
5 files changed
+33 -6

No files matched your search

+3 -2
View File
@@ -17,6 +17,7 @@ import {
AUTH_SESSION_TTL_MS,
MAX_AUTH_SESSIONS,
AUTH_FAILURE_MAX,
AUTH_IP_FAILURE_MAX,
AUTH_FAILURE_WINDOW_MS,
} from '../../config/auth-config.js';
import { getHookSecret, HOOK_SECRET_HEADER } from '../../config/hook-secret.js';
@@ -447,7 +448,7 @@ export function registerAuthMiddleware(app: FastifyInstance, https: boolean, bas
// Rate limit only requests that failed to authenticate on this attempt.
const failures = authFailures.get(clientIp) ?? 0;
if (failures >= AUTH_FAILURE_MAX) {
if (failures >= AUTH_IP_FAILURE_MAX) {
sendAuthRateLimit(reply, authFailures, clientIp);
return;
}
@@ -573,7 +574,7 @@ function registerMultiUserAuthHook(
// Per-IP pre-gate bounds scrypt CPU cost from one source (does NOT gate on the
// per-username bucket here; see below).
const ipFail = authFailures.get(clientIp) ?? 0;
if (ipFail >= AUTH_FAILURE_MAX) {
if (ipFail >= AUTH_IP_FAILURE_MAX) {
sendAuthRateLimit(reply, authFailures, clientIp);
return;
}