From 0382c3241019be984cc8af66411cfe1a00cc4ed1 Mon Sep 17 00:00:00 2001 From: Codex Date: Sun, 7 Jun 2026 13:33:02 +0530 Subject: [PATCH] fix: validate wildcard port allowlist suffixes --- src/mcp/server/transport_security.py | 8 ++++---- tests/server/test_transport_security.py | 4 ++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/mcp/server/transport_security.py b/src/mcp/server/transport_security.py index d9e9f965b..0a34a98bb 100644 --- a/src/mcp/server/transport_security.py +++ b/src/mcp/server/transport_security.py @@ -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}") @@ -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}") diff --git a/tests/server/test_transport_security.py b/tests/server/test_transport_security.py index be28980b5..0a1b1c88e 100644 --- a/tests/server/test_transport_security.py +++ b/tests/server/test_transport_security.py @@ -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"), ],