You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The application has no rate limiting at the Django layer. No rate-limiting library is installed, no middleware is configured, and no decorators are applied to any view.
Priority Endpoints
/admin/login/ - Unlimited password attempts. Primary login is Discord OAuth but any Django user with a password (superusers from createsuperuser) is vulnerable to brute-force.
/d/donations - Triggers update_donations_if_needed.delay() on every request. Unlimited requests can queue thousands of Celery tasks hitting the upstream DonorDrive API.
Current Mitigations
SWAG (NGINX) reverse proxy sits in front of the app and may provide some rate limiting via fail2ban, but this is not verified and is not defense-in-depth
Summary
The application has no rate limiting at the Django layer. No rate-limiting library is installed, no middleware is configured, and no decorators are applied to any view.
Priority Endpoints
/admin/login/- Unlimited password attempts. Primary login is Discord OAuth but any Django user with a password (superusers fromcreatesuperuser) is vulnerable to brute-force./stream/pub/stop,/stream/pub/start,/stream/pub/play- Stream key is sole auth factor. Key space is now ~1 trillion (PR Use cryptographic PRNG and expand wordlist for stream key generation #1024) but there's no lockout or backoff on failed attempts./d/donations- Triggersupdate_donations_if_needed.delay()on every request. Unlimited requests can queue thousands of Celery tasks hitting the upstream DonorDrive API.Current Mitigations
@cache_page) so repeated identical requests don't re-trigger tasks, but cache-busting via varied query params bypasses thisRecommended Approach
django-ratelimitis the lightest option -- decorator-based, per-view control, uses the existing Redis cache backend. No migrations needed.Suggested rates:
/admin/login/- 5 attempts per minute per IP/stream/pub/*- 10 requests per minute per IP/d/donations- 30 requests per minute per IP/d/donations/tracked- 30 requests per minute per IPExample:
Acceptance Criteria
django-ratelimitadded topyproject.tomland lockfiles/stream/pub/*) rate limited/admin/login/rate limited (via middleware or decorator)