feat(security): add CSRF header constants and security-headers endpoint
Move X-BanGUI-Request header name/value to backend/app/utils/constants.py as single source of truth. Add GET /api/v1/config/security-headers endpoint. Update csrf middleware, frontend api client, and docs to use shared constants.
This commit is contained in:
@@ -20,7 +20,7 @@ from fastapi import status
|
||||
from fastapi.responses import JSONResponse
|
||||
from starlette.middleware.base import BaseHTTPMiddleware
|
||||
|
||||
from app.utils.constants import SESSION_COOKIE_NAME
|
||||
from app.utils.constants import CSRF_HEADER_NAME, CSRF_HEADER_VALUE, SESSION_COOKIE_NAME
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from collections.abc import Awaitable, Callable
|
||||
@@ -30,10 +30,6 @@ if TYPE_CHECKING:
|
||||
|
||||
log: structlog.stdlib.BoundLogger = structlog.get_logger()
|
||||
|
||||
# Header name and value that clients must provide for state-mutating requests.
|
||||
_CSRF_HEADER_NAME: str = "X-BanGUI-Request"
|
||||
_CSRF_HEADER_VALUE: str = "1"
|
||||
|
||||
# HTTP methods that require CSRF protection.
|
||||
_CSRF_PROTECTED_METHODS: frozenset[str] = frozenset({"POST", "PUT", "DELETE", "PATCH"})
|
||||
|
||||
@@ -76,8 +72,8 @@ class CsrfMiddleware(BaseHTTPMiddleware):
|
||||
return await call_next(request)
|
||||
|
||||
# Enforce CSRF header for cookie-authenticated state-mutating requests.
|
||||
csrf_header: str | None = request.headers.get(_CSRF_HEADER_NAME)
|
||||
if csrf_header != _CSRF_HEADER_VALUE:
|
||||
csrf_header: str | None = request.headers.get(CSRF_HEADER_NAME)
|
||||
if csrf_header != CSRF_HEADER_VALUE:
|
||||
log.warning(
|
||||
"csrf_validation_failed",
|
||||
method=request.method,
|
||||
|
||||
Reference in New Issue
Block a user