fix(mcp): apply the Host/Origin guard to every HTTP transport - #746
Draft
vishal-bala wants to merge 1 commit into
Draft
vishal-bala wants to merge 1 commit into
vishal-bala wants to merge 1 commit into
Conversation
`run_async` added the DNS-rebinding middleware only when the transport argument was literally "sse" or "streamable-http". FastMCP serves two more cases over HTTP: "http", which is FastMCP's own default HTTP transport name, and an omitted transport, which FastMCP resolves from `fastmcp.settings.transport` (settable through FASTMCP_TRANSPORT). In both, the server bound an HTTP port with no Host or Origin validation. The `rvl mcp` CLI was not affected, because its `--transport` choices are only stdio, sse and streamable-http. An application embedding the server and calling `run_async` itself was. The HTTP transport names are now defined once, as `HTTP_TRANSPORTS` in `transport_security`, and `run_async` tests the transport after resolving an omitted one the way FastMCP does. The CLI's two checks use the same set, so adding "http" to its choices later cannot silently skip the auth warning or the bind arguments. The CLI imports the set lazily, as it does the rest of the MCP code, so `rvl` stays usable without the `mcp` extra. The regression test drives `run_async` with every transport name and with an omitted one resolving to each, and fails three of its seven cases against the previous code.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
The MCP server's DNS-rebinding protection, the Host/Origin validation middleware, was only applied when
run_asyncreceived the literal transport name"sse"or"streamable-http". FastMCP serves two more cases over HTTP. One is"http", which is FastMCP's own default HTTP transport name. The other is an omitted transport, which FastMCP resolves fromfastmcp.settings.transportand therefore fromFASTMCP_TRANSPORT. In both cases the server bound an HTTP port with no Host or Origin validation.The
rvl mcpCLI was not affected, because its--transportchoices are onlystdio,sseandstreamable-http. An application that embeds the server and callsrun_asyncitself was affected.Changes
The HTTP transport names are now defined once, as
HTTP_TRANSPORTSinredisvl/mcp/transport_security.py, andrun_asyncchecks the transport after resolving an omitted one the same way FastMCP does:FastMCP's
run_http_asyncpassesmiddlewaretohttp_appwhatever the transport name, so the middleware takes effect for"http"exactly as it does for"streamable-http".The CLI's
_check_http_authand_servenow use the same set. Nothing changes for CLI users today, but if"http"is later added to the CLI's choices, it can no longer skip the unauthenticated-bind warning or the bind arguments without anyone noticing. The CLI imports the set lazily, as it does the rest of the MCP code, sorvlstays usable without themcpextra.The regression test drives
run_asyncwith each transport name, and with an omitted one resolving tostdio,httporstreamable-http. Against the previous code it fails three of its seven cases:"http", and an omitted transport resolving to either HTTP name.