""" Security headers middleware. Adds HTTP security headers to all responses: - X-Content-Type-Options: Prevent MIME sniffing - X-Frame-Options: Prevent clickjacking - X-XSS-Protection: Enable XSS filter - Strict-Transport-Security: Force HTTPS - Content-Security-Policy: Restrict resource loading """ from starlette.middleware.base import BaseHTTPMiddleware class SecurityHeadersMiddleware(BaseHTTPMiddleware): """Middleware that adds security headers to all responses.""" async def dispatch(self, request, call_next): response = await call_next(request) # Prevent MIME type sniffing response.headers["X-Content-Type-Options"] = "nosniff" # Prevent clickjacking response.headers["X-Frame-Options"] = "DENY" # Enable XSS protection (legacy, but still useful for older browsers) response.headers["X-XSS-Protection"] = "1; mode=block" # Force HTTPS (only if not in dev mode) # Remove this in development if using HTTP response.headers["Strict-Transport-Security"] = "max-age=31536000; includeSubDomains" # Content Security Policy # Note: 'unsafe-inline' and 'unsafe-eval' needed for React and dynamic content # Tighten these in production if possible 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'; " "frame-ancestors 'none';" ) # Referrer policy response.headers["Referrer-Policy"] = "strict-origin-when-cross-origin" # Permissions policy (restrict browser features) response.headers["Permissions-Policy"] = ( "geolocation=(), " "microphone=(), " "camera=(), " "payment=(), " "usb=(), " "magnetometer=()" ) return response