Repository navigation
Description
Correction and scope
The original description overstated the affected configurations. I withdraw the claim that every deployment omitting TransportSecuritySettings is vulnerable.
Read-only source inspection of current main at commit 77001c9 shows:
TransportSecuritySettings.enable_dns_rebinding_protectiondefaults toTrue.TransportSecurityMiddleware(settings=None)explicitly falls back to protection disabled for backward compatibility.- The standard
streamable_http_app()andsse_app()helpers default tohost="127.0.0.1"and automatically enable protection when no explicit settings are supplied and the configured host is127.0.0.1,localhost, or::1. - Direct construction of lower-level HTTP transports without security settings bypasses that helper configuration, including on loopback. Configuring a helper with a non-loopback host without appropriate
transport_securitysettings also leaves these SDK checks disabled. Explicitly disabling protection is another possible configuration.
These are potential exposure paths, not evidence that every such deployment is exploitable. Actual risk depends on browser reachability and other deployment controls. This report is based on source inspection and discussion; it does not include a reproduced attack or a verified vulnerable deployment.
Source: middleware and settings, Streamable HTTP helper, SSE helper.
Previous maintainer decision
#3562 was closed as not planned on October 6, 2026. The maintainer explained that enabling protection unconditionally at the low-level transport layer could reject requests in existing deployments. A bind address such as 0.0.0.0 also does not identify the public hostname needed for an allowlist.
This proposal respects that compatibility decision: retain existing defaults and validation behavior, while making the effective configuration and rejection causes easier to inspect.
Remaining visibility gap
The middleware currently does not log its effective security configuration at initialization. Operators therefore cannot readily distinguish helper-enabled protection, explicit settings, and the disabled fallback from startup logs.
Rejected Host headers produce 421 Invalid Host header; rejected Origin headers produce 403 Invalid Origin header. Existing warnings identify missing or invalid headers, but do not explain the relevant setting or how to correct a proxy/public-host configuration.
This can obscure deployments where protection is disabled and make legitimate Host rejections difficult to diagnose.
Proposed improvement
- Log the effective protection state and configured host/origin allowlists when the transport security configuration is initialized, covering both enabled and disabled states. Warn when protection is disabled and identify
TransportSecuritySettingsas the configuration entry point. - Make Host rejection diagnostics actionable: identify Host validation as the cause, name
TransportSecuritySettings.allowed_hosts, and include a safely escaped, bounded representation of the received Host value—or indicate that it was missing. - Point operators toward explicitly configuring expected public/proxy hostnames and origins. Do not recommend disabling protection as the routine fix or automatically trust a rejected Host value.
Acceptance criteria
- Initialization logging reports the effective
enable_dns_rebinding_protection,allowed_hosts, andallowed_originsvalues after helper configuration has been applied. Disabled configurations produce a warning, including both omitted low-level settings and explicit opt-out. - Tests cover both helpers with each loopback host (
127.0.0.1,localhost,::1), a non-loopback helper configuration without settings, direct low-level construction without settings, and explicit enabled/disabled settings. Logged state matches the actual middleware configuration in each case. - Missing and disallowed Host headers still return HTTP 421. The response identifies
allowed_hostsand the Host validation failure; operator logs include the safely represented received value or an explicit missing-header indicator. - Origin rejection remains distinguishable from Host rejection and retains HTTP 403. Allowed requests and disabled-protection behavior remain unchanged.
- Diagnostics are tested through SSE connection establishment and message POSTs, plus Streamable HTTP requests. Tests include Host values with ports and bracketed IPv6, without changing allowlist matching semantics.
- Header values in diagnostics are escaped and length-limited; responses do not expose the configured allowlists. Rejection guidance does not suggest accepting arbitrary hosts.
- Documentation explains the protected helper defaults, lower-level and non-loopback configuration requirements, and a reverse-proxy example using explicit expected hosts/origins.
Related work and fix check
As of November 14, 2026, inspection of current main and related PRs did not identify a merged implementation of these visibility improvements:
- fix(security): warn on empty allowed_hosts and improve 421/403 response bodies #2694 proposed empty-allowlist warnings and richer rejection bodies; closed without merging.
- fix: explain transport host rejections #2726 proposed structured Host rejection diagnostics; closed without merging. The closing comment cited conflicts and failing CI, so any implementation should be based on current source and tests.
- security: tool description pinning, injection scan, DNS rebinding default fix #3754 included an unconditional default-on change; closed without merging.
Related discussion: #2688 and #1798. This issue focuses on effective-configuration visibility and actionable diagnostics, without reopening the unconditional default-on proposal or asserting a new confirmed vulnerability.
Activity
sattyamjjain commentedon Oct 29, 2026
Ben-Home commentedon Oct 29, 2026
sattyamjjain commentedon Oct 31, 2026
[-]Security: DNS rebinding protection is opt-in, not enabled by default[/-][+]Improve DNS rebinding protection visibility and Host rejection diagnostics[/+]