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:
+13
-1
@@ -40,7 +40,19 @@ def main() -> None:
|
|||||||
logger.info(f" Health: http://{host}:{port}/health")
|
logger.info(f" Health: http://{host}:{port}/health")
|
||||||
logger.info("=" * 60)
|
logger.info("=" * 60)
|
||||||
try:
|
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:
|
except Exception as e:
|
||||||
logger.error(f"Failed to start HTTP server: {e}", exc_info=True)
|
logger.error(f"Failed to start HTTP server: {e}", exc_info=True)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|||||||
Reference in New Issue
Block a user