fix(security): exempt health endpoint from HTTPS enforcement
Docker health checks and load balancers call /health directly without going through the reverse proxy, so they need HTTP access. This fix exempts /health and /metrics endpoints from HTTPS enforcement in production mode. Fixes the issue where Docker health checks were being redirected to HTTPS and failing because there's no TLS on localhost. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -67,3 +67,66 @@ class TestHTTPSEnforcement:
|
||||
response = client.get("/")
|
||||
# TestClient doesn't enforce HTTPS, but middleware should allow it
|
||||
assert response.status_code == 200
|
||||
|
||||
def test_health_endpoint_exempt_from_https_in_production(
|
||||
self, client, monkeypatch
|
||||
):
|
||||
"""Test /health endpoint is accessible via HTTP in production mode.
|
||||
|
||||
Docker health checks and load balancers call the health endpoint directly
|
||||
without going through the reverse proxy, so it must work over HTTP.
|
||||
The key assertion is that we don't get a 301 redirect to HTTPS.
|
||||
"""
|
||||
from gondulf.config import Config
|
||||
|
||||
monkeypatch.setattr(Config, "DEBUG", False)
|
||||
monkeypatch.setattr(Config, "TRUST_PROXY", False)
|
||||
|
||||
# HTTP request to /health should NOT redirect to HTTPS
|
||||
response = client.get(
|
||||
"http://localhost:8000/health", follow_redirects=False
|
||||
)
|
||||
# Should NOT be 301 redirect - actual status depends on DB state (200/503)
|
||||
assert response.status_code != 301
|
||||
# Verify it reached the health endpoint (not redirected)
|
||||
assert response.status_code in (200, 503)
|
||||
|
||||
def test_health_endpoint_head_request_in_production(self, client, monkeypatch):
|
||||
"""Test HEAD request to /health is not redirected in production.
|
||||
|
||||
Docker health checks may use HEAD requests. The key is that the
|
||||
middleware doesn't redirect to HTTPS - the actual endpoint behavior
|
||||
(405 Method Not Allowed) is separate from HTTPS enforcement.
|
||||
"""
|
||||
from gondulf.config import Config
|
||||
|
||||
monkeypatch.setattr(Config, "DEBUG", False)
|
||||
monkeypatch.setattr(Config, "TRUST_PROXY", False)
|
||||
|
||||
# HEAD request to /health should NOT redirect to HTTPS
|
||||
response = client.head(
|
||||
"http://localhost:8000/health", follow_redirects=False
|
||||
)
|
||||
# Should NOT be 301 redirect
|
||||
assert response.status_code != 301
|
||||
|
||||
def test_metrics_endpoint_exempt_from_https_in_production(
|
||||
self, client, monkeypatch
|
||||
):
|
||||
"""Test /metrics endpoint is accessible via HTTP in production mode.
|
||||
|
||||
Monitoring systems may call metrics directly without HTTPS.
|
||||
"""
|
||||
from gondulf.config import Config
|
||||
|
||||
monkeypatch.setattr(Config, "DEBUG", False)
|
||||
monkeypatch.setattr(Config, "TRUST_PROXY", False)
|
||||
|
||||
# HTTP request to /metrics should not be redirected
|
||||
# (endpoint may not exist yet, but should not redirect to HTTPS)
|
||||
response = client.get(
|
||||
"http://localhost:8000/metrics", follow_redirects=False
|
||||
)
|
||||
# Should return 404 (not found) not 301 (redirect to HTTPS)
|
||||
assert response.status_code != 301
|
||||
|
||||
|
||||
Reference in New Issue
Block a user