fix(transport-security): compare Host and Origin case-insensitively (#3437)

Closed
AM
2mo ago
+32-6

Summary

Fixes #3437.

TransportSecurityMiddleware._validate_host() and _validate_origin() previously compared incoming Host and Origin headers against allowed_hosts and allowed_origins case-sensitively.

Per RFC 9110 §4.2.3 and RFC 6454 §4:

  • "The scheme and host are case-insensitive and normally provided in lowercase; all other components are compared in a case-sensitive manner."

Every WHATWG URL-based HTTP client (browsers, Node fetch, undici, and mcp-remote) automatically lowercases hostnames before transmitting them. On Windows, where %COMPUTERNAME% is uppercase by default, configuring allowed_hosts=["MYHOST:*"] caused all incoming requests from standard fetch clients (e.g. Host: myhost:8000) to be rejected with 421 Misdirected Request.

Changes

  • In src/mcp/server/transport_security.py:
    • _validate_host(): Lowercases both the incoming Host header and allowed_hosts items before exact and wildcard-port comparisons.
    • _validate_origin(): Lowercases both the incoming Origin header and allowed_origins items before exact and wildcard-port comparisons.
  • In tests/server/test_transport_security.py:
    • Added test cases covering uppercase and mixed-case Host and Origin values against lowercase allowlists.
    • Added test_validate_request_case_insensitive_uppercase_settings asserting that uppercase allowlist configurations (such as Windows %COMPUTERNAME%) correctly permit lowercase client requests.

Verification

  • Ran uv run pytest tests/server/test_transport_security.py: 31/31 passed in 0.11s.
  • Checked with uv run ruff check and uv run ruff format --check: 100% clean.