fix(webui): require proxy-generated auth assertions

This commit is contained in:
concertypin
2026-08-04 21:53:16 +08:00
committed by Xubin Ren
parent 465a918cf8
commit e318e21cad
4 changed files with 45 additions and 4 deletions
+23
View File
@@ -93,6 +93,24 @@ from nanobot.webui.websocket_logging import websockets_server_logger
_WEBUI_HTTP_OPEN_TIMEOUT_S = 360.0
_ROUTING_ASSERTION_HEADERS = frozenset(
{
"host",
"forwarded",
"x-forwarded-for",
"x-forwarded-host",
"x-forwarded-proto",
"x-real-ip",
"cf-connecting-ip",
}
)
def _is_routing_assertion_header(value: str) -> bool:
normalized = value.casefold()
return normalized in _ROUTING_ASSERTION_HEADERS or normalized.startswith("x-forwarded-")
class TrustedProxyAuthConfig(Base):
"""Authentication assertions accepted from explicitly trusted proxy peers."""
@@ -128,6 +146,11 @@ class TrustedProxyAuthConfig(Base):
value = value.strip()
if not value or any(char.isspace() or ord(char) < 0x21 for char in value):
raise ValueError("assertion_header must be a valid HTTP header name")
if _is_routing_assertion_header(value):
raise ValueError(
"assertion_header must identify a proxy-generated authentication assertion, "
"not a routing or client metadata header"
)
return value
@model_validator(mode="after")
@@ -3473,6 +3473,16 @@ def test_trusted_proxy_rejects_invalid_or_universal_cidrs(
with pytest.raises(ValidationError):
WebSocketConfig.model_validate(_trusted_proxy_config([cidr]))
@pytest.mark.parametrize(
"assertion_header",
["Host", "Forwarded", "X-Forwarded-For", "X-Real-IP", "CF-Connecting-IP"],
)
def test_trusted_proxy_rejects_routing_headers(assertion_header: str) -> None:
from pydantic_core import ValidationError
with pytest.raises(ValidationError, match="proxy-generated"):
WebSocketConfig.model_validate(_trusted_proxy_config(assertion_header=assertion_header))
def test_wildcard_host_without_auth_raises_on_startup(bus: MagicMock) -> None:
import pytest
from pydantic_core import ValidationError