Harden auth, CSRF, and email log UX
This commit is contained in:
36
app.py
36
app.py
@@ -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 名称不变) ====================
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user