Files
FastapiAdmin/backend/app/core/middleware/security_headers.py
T
zhangtao 53d2a9d13e chore: cleanup old frontend code and update project configs
This commit removes the deprecated frontend/web-old directory, updates various project configuration files including tsconfig, vite config, environment variables, and backend data models. It also fixes several API paths, adds tenant awareness to multiple models, and makes minor UI adjustments.
2026-05-27 01:12:03 +08:00

87 lines
2.9 KiB
Python

"""安全响应头中间件
自动为每个 HTTP 响应注入安全相关响应头,防护常见 Web 攻击。
"""
from starlette.middleware.base import BaseHTTPMiddleware, RequestResponseEndpoint
from starlette.requests import Request
from starlette.responses import Response
from starlette.types import ASGIApp
class SecurityHeadersMiddleware(BaseHTTPMiddleware):
"""安全响应头中间件
注入以下安全响应头:
- Strict-Transport-Security (HSTS): 强制 HTTPS 连接(根据配置开关)
- X-Content-Type-Options: 禁止 MIME 类型嗅探
- X-Frame-Options: 禁止页面被嵌入 iframe(防点击劫持)
- X-XSS-Protection: 启用浏览器 XSS 过滤器
- Referrer-Policy: 控制 Referer 信息传递
- Permissions-Policy: 限制浏览器 API 使用
- Content-Security-Policy: 内容安全策略
"""
def __init__(self, app: ASGIApp) -> None:
"""初始化安全响应头中间件
HSTS 开关从 settings.HSTS_ENABLE 读取。
参数:
app: ASGI 应用实例
"""
super().__init__(app)
from app.config.setting import settings
self._hsts = settings.HSTS_ENABLE
async def dispatch(self, request: Request, call_next: RequestResponseEndpoint) -> Response:
"""处理请求并注入安全响应头
参数:
request: Starlette 请求对象
call_next: 下一个中间件/路由处理器
返回:
Response: 带安全响应头的 HTTP 响应
"""
response = await call_next(request)
# HSTS(仅生产环境启用)
if self._hsts:
response.headers["Strict-Transport-Security"] = (
"max-age=31536000; includeSubDomains; preload"
)
# 禁止 MIME 类型嗅探
response.headers["X-Content-Type-Options"] = "nosniff"
# 禁止嵌入 iframe(防止点击劫持)
response.headers["X-Frame-Options"] = "DENY"
# 启用浏览器 XSS 过滤器
response.headers["X-XSS-Protection"] = "1; mode=block"
# 控制 Referer 信息
response.headers["Referrer-Policy"] = "strict-origin-when-cross-origin"
# 限制浏览器 API 权限
response.headers["Permissions-Policy"] = (
"camera=(), microphone=(), geolocation=(), "
"payment=(), usb=(), magnetometer=(), "
"gyroscope=(), speaker=(), vibrate=()"
)
# 内容安全策略(基础级别,可按需收紧)
response.headers["Content-Security-Policy"] = (
"default-src 'self'; "
"script-src 'self' 'unsafe-inline' 'unsafe-eval'; "
"style-src 'self' 'unsafe-inline'; "
"img-src 'self' data: https:; "
"font-src 'self' data:; "
"connect-src 'self' https:; "
"frame-ancestors 'none'"
)
return response