fix: conditional HSTS via FORCE_HTTPS, safe for enterprise without certs
HSTS (Strict-Transport-Security) is now opt-in via FORCE_HTTPS=true. Without it enabled, no HSTS header is sent — safe for dev environments and enterprise deployments behind HTTP-only proxies without HTTPS certs. When FORCE_HTTPS=true, sends 'max-age=31536000; includeSubDomains'. Enterprise recommendation: set HSTS at nginx/ingress level instead. .env.example documents the risk: enabling without certs breaks site access.
This commit is contained in:
@@ -191,11 +191,23 @@ app.add_middleware(
|
||||
)
|
||||
|
||||
# HSTS — Strict-Transport-Security header (see [SEC:L-2])
|
||||
# Only active when FORCE_HTTPS=true (enterprise deployments with proper certs).
|
||||
# In dev or behind HTTP-only proxies, HSTS is disabled to avoid lockout.
|
||||
class HSTSMiddleware(BaseHTTPMiddleware):
|
||||
"""Add Strict-Transport-Security header to every response."""
|
||||
"""Add Strict-Transport-Security header when FORCE_HTTPS=true.
|
||||
|
||||
Enterprise note: In production, set HSTS at the nginx/ingress level
|
||||
(add_header Strict-Transport-Security ...). This middleware is a
|
||||
fallback for environments where nginx is not configured to do so.
|
||||
"""
|
||||
def __init__(self, app):
|
||||
super().__init__(app)
|
||||
self._enabled = os.getenv("FORCE_HTTPS", "").strip().lower() in {"1", "true", "yes"}
|
||||
|
||||
async def dispatch(self, request: Request, call_next):
|
||||
response = await call_next(request)
|
||||
response.headers["Strict-Transport-Security"] = "max-age=31536000; includeSubDomains"
|
||||
if self._enabled:
|
||||
response.headers["Strict-Transport-Security"] = "max-age=31536000; includeSubDomains"
|
||||
return response
|
||||
|
||||
app.add_middleware(HSTSMiddleware)
|
||||
|
||||
Reference in New Issue
Block a user