Spaces:
Sleeping
Sleeping
| """Bridge response security headers — P8 CP-C. | |
| Pure starlette middleware. Adds the minimal browser-side protections | |
| expected of an API origin. The Next.js web frontend has its own | |
| (stricter) CSP for HTML responses; this module covers the bridge. | |
| """ | |
| from __future__ import annotations | |
| from starlette.middleware.base import BaseHTTPMiddleware | |
| _HEADERS: dict[str, str] = { | |
| "Content-Security-Policy": "default-src 'none'; frame-ancestors 'none'", | |
| "Strict-Transport-Security": "max-age=63072000; includeSubDomains", | |
| "X-Frame-Options": "DENY", | |
| "X-Content-Type-Options": "nosniff", | |
| "Referrer-Policy": "strict-origin-when-cross-origin", | |
| "Permissions-Policy": "camera=(), microphone=(), geolocation=(), interest-cohort=()", | |
| } | |
| class SecurityHeadersMiddleware(BaseHTTPMiddleware): | |
| """Adds security headers to every response. | |
| Uses `setdefault` semantics so route handlers can opt-out per header | |
| (e.g. Cache-Control). HSTS on HTTP responses is harmless — browsers | |
| ignore it outside HTTPS. | |
| """ | |
| async def dispatch(self, request, call_next): | |
| response = await call_next(request) | |
| for k, v in _HEADERS.items(): | |
| if k not in response.headers: | |
| response.headers[k] = v | |
| return response | |