fix(mcp): disable DNS-rebinding protection on FastMCP
FastMCP defaults to an allow-list of localhost variants for the Host header (DNS-rebinding protection). Any deployment behind a reverse proxy hitting a non-localhost hostname (e.g. devassistant.traefik.internal) gets 421 Misdirected Request with: WARNING mcp.server.transport_security: Invalid Host header: <name> The protection exists to stop a malicious browser page from rebinding DNS to attack a localhost MCP server. Our deployment is HTTP transport behind a reverse proxy with bearer-token auth, which already gates every request — so the rebinding threat doesn't apply. Disabling the check lets any Host through; auth still rejects unauthorized requests at 401. This also makes the integration test pass without test-only host hackery — every realistic Host header (Traefik internal hostname, CDN domain, custom DNS) now reaches FastMCP cleanly. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from mcp.server.fastmcp import FastMCP
|
from mcp.server.fastmcp import FastMCP
|
||||||
|
from mcp.server.transport_security import TransportSecuritySettings
|
||||||
from quart import Quart
|
from quart import Quart
|
||||||
|
|
||||||
_INSTRUCTIONS = """
|
_INSTRUCTIONS = """
|
||||||
@@ -23,8 +24,24 @@ Hierarchy: Project -> Milestone -> Task/Note.
|
|||||||
|
|
||||||
|
|
||||||
def build_mcp_server() -> FastMCP:
|
def build_mcp_server() -> FastMCP:
|
||||||
"""Build the FastMCP instance with all tools registered."""
|
"""Build the FastMCP instance with all tools registered.
|
||||||
mcp = FastMCP("scribe", instructions=_INSTRUCTIONS.strip())
|
|
||||||
|
DNS-rebinding protection is disabled: FastMCP's default allow-list is
|
||||||
|
just localhost variants, which means any deployment behind a reverse
|
||||||
|
proxy (Traefik with a hostname like devassistant.traefik.internal,
|
||||||
|
Cloudflare, nginx, etc.) gets 421 Misdirected Request. The threat
|
||||||
|
model that protection addresses — a malicious browser page rebinding
|
||||||
|
DNS to hit a localhost MCP — doesn't apply here: this is HTTP transport
|
||||||
|
behind a reverse proxy with bearer-token auth as the real security
|
||||||
|
boundary.
|
||||||
|
"""
|
||||||
|
mcp = FastMCP(
|
||||||
|
"scribe",
|
||||||
|
instructions=_INSTRUCTIONS.strip(),
|
||||||
|
transport_security=TransportSecuritySettings(
|
||||||
|
enable_dns_rebinding_protection=False,
|
||||||
|
),
|
||||||
|
)
|
||||||
from fabledassistant.mcp.tools import register_all
|
from fabledassistant.mcp.tools import register_all
|
||||||
register_all(mcp)
|
register_all(mcp)
|
||||||
return mcp
|
return mcp
|
||||||
|
|||||||
Reference in New Issue
Block a user