## 28) Login failure delay can enable app-layer DoS

This commit is contained in:
2026-04-29 19:02:00 +02:00
parent 1e2576af2a
commit 9072117db3
6 changed files with 119 additions and 46 deletions

View File

@@ -22,7 +22,7 @@ from __future__ import annotations
import asyncio
import structlog
from fastapi import APIRouter, Request, Response, status
from fastapi import APIRouter, Request, Response
from app.dependencies import (
AuthDep,
@@ -98,11 +98,16 @@ async def login(
session_repo=session_ctx.session_repo,
)
except ValueError as exc:
# Add delay on wrong password to slow down brute-force attacks.
# The bcrypt checkpw already takes ~100ms at cost factor 12,
# but an extra 10 seconds makes automation much less feasible.
await asyncio.sleep(10.0)
log.warning("login_failed", client_ip=client_ip, error=str(exc))
# Progressive penalty delay on wrong password to slow down brute-force
# attacks without exhausting request capacity (app-layer DoS resistance).
penalty = rate_limiter.record_failure(client_ip)
acquired = rate_limiter.acquire(client_ip)
try:
if acquired:
await asyncio.sleep(penalty)
finally:
rate_limiter.release(client_ip)
log.warning("login_failed", client_ip=client_ip, error=str(exc), penalty=penalty)
raise AuthenticationError(str(exc)) from exc
response.set_cookie(