fix(security): suppress uvicorn server-version banner + trust proxy headers

- server_header=False — uvicorn was adding "server: uvicorn" after our
  middleware ran, defeating the banner-strip in security_headers().
- proxy_headers + forwarded_allow_ips=* — so request.client.host
  reflects the real client IP from X-Forwarded-For (Traefik), which
  is what the per-IP rate limiter keys on.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-25 18:27:03 +00:00
parent 901e9c75b0
commit c4d3699669
+13 -1
View File
@@ -40,7 +40,19 @@ def main() -> None:
logger.info(f" Health: http://{host}:{port}/health")
logger.info("=" * 60)
try:
uvicorn.run(app, host=host, port=port, log_level="info")
# server_header=False stops uvicorn from advertising its name+version;
# date_header=False is harmless and trims one more byte of fingerprint.
# proxy_headers=True + forwarded_allow_ips="*" so request.client.host
# reflects the real client IP behind Traefik (used by the rate limiter).
uvicorn.run(
app,
host=host,
port=port,
log_level="info",
server_header=False,
proxy_headers=True,
forwarded_allow_ips="*",
)
except Exception as e:
logger.error(f"Failed to start HTTP server: {e}", exc_info=True)
sys.exit(1)