PC3 Phase 3.3: rate-limit the auth endpoints
app/rate_limit.py: an in-process sliding-window limiter (single-worker backend, so no Redis needed -- flagged for if that changes). /register and /login are capped at 10 attempts / minute / client IP (X-Forwarded-For aware), returning 429 + Retry-After past that. Blunts credential brute-force, which the backend had no protection against. - conftest.py resets the limiter between tests (every TestClient request looks like one IP). - tests/test_rate_limit.py: threshold, shared bucket, per-key window. 77 passed. CORS reviewed while here: already an explicit origin allowlist (settings.CORS_ORIGINS), not "*" -- and the Godot client isn't a browser so it doesn't apply there anyway. Left as-is. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015jtxAiu5dAW4WxCNdGkrkJ
This commit is contained in:
@@ -132,6 +132,17 @@ def _reset_database():
|
||||
yield
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def _reset_rate_limiter():
|
||||
"""Every TestClient request looks like the same client IP, so the
|
||||
per-IP auth limiter would trip mid-suite. Clear it between tests; the
|
||||
dedicated rate-limit test disables this to exercise the real behaviour.
|
||||
"""
|
||||
from app import rate_limit
|
||||
rate_limit.reset_all()
|
||||
yield
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def _override_db():
|
||||
"""Override get_db so the app uses a fresh session per test.
|
||||
|
||||
Reference in New Issue
Block a user