fix(transport-security): compare Host and Origin case-insensitively (#3437)
Closed
AM
2mo ago+32+32+01234567890123456789-6-6-0123456789
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 incomingHostheader andallowed_hostsitems before exact and wildcard-port comparisons._validate_origin(): Lowercases both the incomingOriginheader andallowed_originsitems before exact and wildcard-port comparisons.
- In
tests/server/test_transport_security.py:- Added test cases covering uppercase and mixed-case
HostandOriginvalues against lowercase allowlists. - Added
test_validate_request_case_insensitive_uppercase_settingsasserting that uppercase allowlist configurations (such as Windows%COMPUTERNAME%) correctly permit lowercase client requests.
- Added test cases covering uppercase and mixed-case
Verification
- Ran
uv run pytest tests/server/test_transport_security.py: 31/31 passed in 0.11s. - Checked with
uv run ruff checkanduv run ruff format --check: 100% clean.