Arag / app /middleware /security_headers.py
AuthorBot
Fix: CSP connect-src for jsdelivr + better create author error display
6d85d9d
Raw
History Blame Contribute Delete
2.3 kB
"""Author RAG Chatbot SaaS — Security Headers Middleware.
Adds production-grade security headers to every HTTP response using pure ASGI
(avoids BaseHTTPMiddleware request body consumption issues).
"""
from starlette.types import ASGIApp, Receive, Scope, Send
from app.config import get_settings
class SecurityHeadersMiddleware:
"""Add security headers to all HTTP responses (pure ASGI)."""
def __init__(self, app: ASGIApp) -> None:
self.app = app
async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
if scope["type"] != "http":
await self.app(scope, receive, send)
return
cfg = get_settings()
use_hsts = cfg.APP_ENV == "production"
async def send_with_headers(message):
if message["type"] == "http.response.start":
headers = list(message.get("headers", []))
security_headers = [
(b"x-content-type-options", b"nosniff"),
(b"x-frame-options", b"SAMEORIGIN"),
(b"x-xss-protection", b"1; mode=block"),
(b"referrer-policy", b"strict-origin-when-cross-origin"),
(b"permissions-policy", b"camera=(), microphone=(), geolocation=(), payment=()"),
# R-043: CSP — primary XSS defense
(b"content-security-policy",
b"default-src 'self'; "
b"script-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net; "
b"style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; "
b"font-src 'self' https://fonts.gstatic.com; "
b"img-src 'self' data: https:; "
b"connect-src 'self' https://api.openai.com https://cdn.jsdelivr.net; "
b"frame-ancestors 'none'"),
]
if use_hsts:
security_headers.insert(
0,
(b"strict-transport-security", b"max-age=31536000; includeSubDomains"),
)
headers.extend(security_headers)
message["headers"] = headers
await send(message)
await self.app(scope, receive, send_with_headers)