Skip to content

Enforce 2026-07-28 Origin validation semantics #1191

Closed

Description

@lucarlig

Is your feature request related to a problem? Please describe.

The MCP 2026-07-28 Streamable HTTP specification requires servers to validate every present Origin header and return HTTP 403 Forbidden when it is invalid.

RMCP currently differs in two ways:

  • An empty allowed_origins list skips Origin validation, so any present Origin is accepted.
  • Malformed or non-UTF-8 Origin values return HTTP 400 instead of the required 403.

Requests without an Origin header should continue to pass for non-browser MCP clients.

Describe the solution you'd like

  • Keep Origin validation enabled by default.
  • Treat an empty allowed_origins list as allowing no present Origin values.
  • Preserve disable_allowed_origins() as the explicit opt-out from validation.
  • Return HTTP 403 for malformed, non-UTF-8, and non-allowlisted Origin values.
  • Leave existing port-matching behavior unchanged because the MCP specification does not define allowlist matching semantics.

Describe alternatives you've considered

  • Keeping an empty allowlist as an implicit way to disable validation. This makes an empty security policy accept every present Origin and duplicates the explicit disable_allowed_origins() option.
  • Returning HTTP 400 for malformed Origin values. This does not match the specification's required HTTP 403 response for an invalid present Origin.
  • Changing port-matching behavior at the same time. This is left unchanged because the specification does not define allowlist matching semantics.

Additional context

This changes the default behavior only for requests that carry an Origin header. Non-browser clients without that header remain unaffected. Deployments that intentionally accept arbitrary Origins can continue to call disable_allowed_origins().

Acceptance criteria:

  • Empty allowlist + present Origin returns 403.
  • Empty allowlist + missing Origin succeeds.
  • Explicitly disabled validation accepts a present Origin.
  • Malformed and non-UTF-8 Origin values return 403.
  • Existing allowlist and missing-Origin tests continue to pass.

Specification: https://modelcontextprotocol.io/specification/2026-07-28/basic/transports/streamable-http

Related bug: #1188

Activity

  1. added
    P2Medium: important but non-blocking improvement
    on Aug 20, 2026
  2. acamarata commented on Aug 25, 2026

    @acamarata

    I'd like to pick this up, and I think #1188 should land in the same change.

    #1188 is the malformed-Origin case of this issue: it reports 400 where the 2026-07-28 spec requires 403. That is one branch of the validation logic described here, so splitting them would mean touching the same code path twice and leaving the tree briefly inconsistent between the two merges.

    Proposed behavior, matching what you outlined:

    • Origin validation stays on by default
    • A present Origin that is malformed or non-UTF-8 returns 403, not 400
    • An empty allowed_origins list allows no present Origin values, rather than skipping validation
    • Requests with no Origin header continue to pass, for non-browser clients
    • disable_allowed_origins() remains the explicit opt-out

    Tests would cover the four cases separately: absent, valid-and-allowed, valid-but-not-allowlisted, and malformed. The last two both return 403 but for different reasons, and they're worth asserting independently so a future refactor can't collapse them.

    Happy to split it into two PRs if you'd rather review them separately.

  3. lucarlig commented on Aug 25, 2026

    @lucarlig
    ContributorAuthor

    @acamarata I already have #1192

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Medium: important but non-blocking improvement

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions