Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/mcp/server/transport_security.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ def _validate_host(self, host: str | None) -> bool:
if allowed.endswith(":*"):
# Extract base host from pattern
base_host = allowed[:-2]
# Check if the actual host starts with base host and has a port
if host.startswith(base_host + ":"):
# Check if the actual host is base host plus a numeric port.
if host.startswith(base_host + ":") and host[len(base_host) + 1 :].isdigit():
return True

logger.warning(f"Invalid Host header: {host}")
Expand All @@ -77,8 +77,8 @@ def _validate_origin(self, origin: str | None) -> bool:
if allowed.endswith(":*"):
# Extract base origin from pattern
base_origin = allowed[:-2]
# Check if the actual origin starts with base origin and has a port
if origin.startswith(base_origin + ":"):
# Check if the actual origin is base origin plus a numeric port.
if origin.startswith(base_origin + ":") and origin[len(base_origin) + 1 :].isdigit():
return True

logger.warning(f"Invalid Origin header: {origin}")
Expand Down
4 changes: 4 additions & 0 deletions tests/server/test_transport_security.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,14 @@ def _request(host: str | None, origin: str | None, content_type: str | None = "a
pytest.param(None, None, 421, id="missing-host"),
pytest.param("evil.example", None, 421, id="host-no-match"),
pytest.param("evil.example:9000", None, 421, id="host-wildcard-base-mismatch"),
pytest.param("wild.example:9000.evil", None, 421, id="host-wildcard-port-suffix"),
pytest.param("wild.example:notaport", None, 421, id="host-wildcard-nonnumeric-port"),
pytest.param("good.example", None, None, id="host-exact-no-origin"),
pytest.param("wild.example:9000", None, None, id="host-wildcard-match"),
pytest.param("good.example", "http://evil.example", 403, id="origin-no-match"),
pytest.param("good.example", "http://evil.example:9000", 403, id="origin-wildcard-base-mismatch"),
pytest.param("good.example", "http://wild.example:9000.evil", 403, id="origin-wildcard-port-suffix"),
pytest.param("good.example", "http://wild.example:notaport", 403, id="origin-wildcard-nonnumeric-port"),
pytest.param("good.example", "http://good.example", None, id="origin-exact"),
pytest.param("good.example", "http://wild.example:9000", None, id="origin-wildcard-match"),
],
Expand Down
Loading