Login Rate Limit Reactivation Limit Persistent Sessions
This commit is contained in:
parent
dc180a1e8a
commit
bcaf8ae706
|
|
@ -20,7 +20,26 @@ import asyncio
|
|||
import discord
|
||||
from discord.ui import Button, View
|
||||
from dotenv import load_dotenv
|
||||
import time as _time
|
||||
load_dotenv()
|
||||
|
||||
# ---- Simple login rate limiter (per IP, 0.5s min interval) ----
|
||||
_login_last_attempt: dict = {} # {ip: timestamp}
|
||||
_LOGIN_RATE_LIMIT_SECONDS = 0.5
|
||||
|
||||
def _check_login_rate_limit(ip: str) -> bool:
|
||||
"""Returns True if the request is allowed, False if rate-limited."""
|
||||
now = _time.time()
|
||||
last = _login_last_attempt.get(ip, 0)
|
||||
if now - last < _LOGIN_RATE_LIMIT_SECONDS:
|
||||
return False
|
||||
_login_last_attempt[ip] = now
|
||||
# Cleanup old entries to prevent unbounded growth
|
||||
if len(_login_last_attempt) > 10000:
|
||||
cutoff = now - 60
|
||||
for k in [k for k, v in list(_login_last_attempt.items()) if v < cutoff]:
|
||||
_login_last_attempt.pop(k, None)
|
||||
return True
|
||||
async_mode = "eventlet"
|
||||
app = Flask(__name__,
|
||||
template_folder='Frontend/HTML',
|
||||
|
|
@ -53,7 +72,7 @@ class SuppressServerLoadFilter(logging.Filter):
|
|||
log = logging.getLogger('werkzeug')
|
||||
log.addFilter(SuppressServerLoadFilter())
|
||||
app.secret_key = os.environ.get('SECRET_KEY', os.urandom(32))
|
||||
app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(hours=8)
|
||||
app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(days=30)
|
||||
app.config['SESSION_COOKIE_SECURE'] = True
|
||||
app.config['SESSION_COOKIE_HTTPONLY'] = True
|
||||
app.config['SESSION_COOKIE_SAMESITE'] = 'Lax'
|
||||
|
|
@ -658,6 +677,11 @@ def login():
|
|||
if maintenance_status and maintenance_status.get('enabled', False):
|
||||
return redirect(url_for('maintenance'))
|
||||
if request.method == 'POST':
|
||||
# Rate limit: max 1 attempt per 0.5s per IP
|
||||
_client_ip = request.headers.get('X-Forwarded-For', request.remote_addr or '').split(',')[0].strip()
|
||||
if not _check_login_rate_limit(_client_ip):
|
||||
flash("Zu viele Anmeldeversuche. Bitte warte einen Moment.", "warning")
|
||||
return render_template('login.html')
|
||||
username = request.form.get('username')
|
||||
password = request.form.get('password')
|
||||
if not username or not password:
|
||||
|
|
|
|||
Loading…
Reference in a new issue