Skip to content

feat: add Origin header validation to MapMcp endpoints - #1819

Open
ez-lbz wants to merge 1 commit into
modelcontextprotocol:mainfrom
ez-lbz:add-origin-validation
Open

feat: add Origin header validation to MapMcp endpoints#1819
ez-lbz wants to merge 1 commit into
modelcontextprotocol:mainfrom
ez-lbz:add-origin-validation

Conversation

@ez-lbz

@ez-lbz ez-lbz commented Aug 16, 2026

Copy link
Copy Markdown

Description

Adds default Origin header validation to the MCP endpoints mapped by MapMcp, so the ASP.NET Core server rejects cross-origin browser requests by default instead of relying on external mitigation.

The Streamable HTTP spec requires servers to validate the Origin header for browser clients. Currently the C# ASP.NET Core integration performs no origin validation — MapMcp() only registers routes, and the docs point users at external CORS/Kestrel configuration, leaving the default posture fail-open.

Behavior

Requests are handled as follows:

  • No Origin header (SDK clients, curl, other non-browser callers) — always allowed.
  • Origin host and port match the request Host header (same-origin) — allowed.
  • Loopback origins (localhost, 127.0.0.1, [::1]) — allowed by default, so browsers running on the same machine (e.g. a frontend dev server) work without configuration.
  • Any other cross-origin request — 403 Forbidden.
  • Origins can be opted in via HttpServerTransportOptions.AllowedOrigins, and validation can be turned off entirely via HttpServerTransportOptions.DisableOriginValidation.

The scheme is intentionally not compared when matching the request host, since TLS is commonly terminated at a reverse proxy.

Implementation

  • HttpServerTransportOptions gains AllowedOrigins and DisableOriginValidation.
  • New OriginValidationEndpointFilter is registered on the MapMcp route group as an endpoint filter when validation is enabled, applying to both the Streamable HTTP and (when enabled) legacy SSE endpoints. CORS preflight OPTIONS requests are unaffected — they are answered by the CORS middleware before endpoint execution.
  • Docs updated to describe the new default and how to customize or disable it.

Tests

Added OriginValidationTests covering requests with no Origin, same-origin, loopback (localhost, 127.0.0.1, [::1]), cross-origin (403), malformed origin, explicitly allowed origins, and the disabled opt-out.

Checklist

  • Tests pass (via CI — no local toolchain available)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant