Security Vulnerability
JWT access tokens are configured to expire in 90 days, which is far beyond security best practices.
Affected File
api/leaderboard/settings.py:88-89
Problem
SIMPLE_JWT = {
"ACCESS_TOKEN_LIFETIME": timedelta(days=90),
"REFRESH_TOKEN_LIFETIME": timedelta(days=90),
...
}
Standard practice is:
- Access tokens: 5-30 minutes (short-lived, frequently rotated)
- Refresh tokens: Days to weeks (longer-lived, revocable)
A 90-day access token means if one is stolen (via log file, browser extension, XSS, MITM), the attacker has persistent access for 3 full months without needing the refresh token. There's no way to revoke an access token mid-lifetime with standard JWT.
Proposed Fix
SIMPLE_JWT = {
"ACCESS_TOKEN_LIFETIME": timedelta(minutes=30),
"REFRESH_TOKEN_LIFETIME": timedelta(days=90), # Stays long for user convenience
"ROTATE_REFRESH_TOKENS": True,
"BLACKLIST_AFTER_ROTATION": True, # Already set, good
...
}
The 90-day refresh token is acceptable because it gets rotated and blacklisted on each use (ROTATE_REFRESH_TOKENS: True, BLACKLIST_AFTER_ROTATION: True). But access tokens should be short-lived since they can't be revoked.
Severity
HIGH — Significantly expands the attack window for stolen tokens.
Security Vulnerability
JWT access tokens are configured to expire in 90 days, which is far beyond security best practices.
Affected File
api/leaderboard/settings.py:88-89Problem
Standard practice is:
A 90-day access token means if one is stolen (via log file, browser extension, XSS, MITM), the attacker has persistent access for 3 full months without needing the refresh token. There's no way to revoke an access token mid-lifetime with standard JWT.
Proposed Fix
The 90-day refresh token is acceptable because it gets rotated and blacklisted on each use (
ROTATE_REFRESH_TOKENS: True, BLACKLIST_AFTER_ROTATION: True). But access tokens should be short-lived since they can't be revoked.Severity
HIGH — Significantly expands the attack window for stolen tokens.