Harden auth, CSRF, and email log UX

This commit is contained in:
2025-12-26 19:05:20 +08:00
parent 3214cbbd91
commit f90b0a4f11
47 changed files with 583 additions and 198 deletions

36
app.py
View File

@@ -18,8 +18,8 @@ import signal
import sys
import threading
from flask import Flask, jsonify, redirect, request, send_from_directory, url_for
from flask_login import LoginManager
from flask import Flask, jsonify, redirect, request, send_from_directory, session, url_for
from flask_login import LoginManager, current_user
from flask_socketio import SocketIO
import database
@@ -27,7 +27,7 @@ import db_pool
import email_service
from app_config import get_config
from app_logger import get_logger, init_logging
from app_security import is_safe_path
from app_security import generate_csrf_token, is_safe_path, validate_csrf_token
from browser_pool_worker import init_browser_worker_pool, shutdown_browser_worker_pool
from realtime.socketio_handlers import register_socketio_handlers
from realtime.status_push import status_push_worker
@@ -128,6 +128,36 @@ def unauthorized():
return redirect(url_for("pages.login_page", next=request.url))
@app.before_request
def enforce_csrf_protection():
if request.method in {"GET", "HEAD", "OPTIONS"}:
return
if request.path.startswith("/static/"):
return
if not (current_user.is_authenticated or "admin_id" in session):
return
token = request.headers.get("X-CSRF-Token") or request.form.get("csrf_token")
if not token or not validate_csrf_token(token):
return jsonify({"error": "CSRF token missing or invalid"}), 403
@app.after_request
def ensure_csrf_cookie(response):
if request.path.startswith("/static/"):
return response
token = session.get("csrf_token")
if not token:
token = generate_csrf_token()
response.set_cookie(
"csrf_token",
token,
httponly=False,
secure=bool(config.SESSION_COOKIE_SECURE),
samesite=config.SESSION_COOKIE_SAMESITE,
)
return response
# ==================== 静态文件(保持 endpoint 名称不变) ====================