Skip to content

Fix/stdio jsonrpc handshake#367

Open
Pnkcaht wants to merge 1 commit intodocker:mainfrom
Pnkcaht:fix/stdio-jsonrpc-handshake
Open

Fix/stdio jsonrpc handshake#367
Pnkcaht wants to merge 1 commit intodocker:mainfrom
Pnkcaht:fix/stdio-jsonrpc-handshake

Conversation

@Pnkcaht
Copy link
Contributor

@Pnkcaht Pnkcaht commented Jan 26, 2026

What I did

Updated the MCP Gateway transport layer to safely handle HTTP-based requests by validating the Origin header and aligning the stdio transport lifecycle with other transports.

The gateway now correctly blocks non-localhost browser origins to prevent DNS rebinding and cross-origin attacks, while preserving compatibility with CLI and SDK clients that do not send an Origin header.
This allows the MCP Gateway to be tested and run locally with HTTP / streaming transports in a secure and predictable way.

Related issue

Fixed #336

What was the problem?

When running the MCP Gateway locally using HTTP-based transports (streaming / SSE), the gateway accepted requests from arbitrary browser origins.

Specifically:

  • No validation was performed on the Origin header
  • Malicious cross-origin browser requests could reach the MCP endpoint
  • DNS rebinding and subdomain-based attacks were possible
  • There was no clear distinction between:
  • Browser traffic (must be restricted)
  • CLI / SDK traffic (must continue working without Origin)

Additionally:

  • The stdio transport blocked the gateway startup flow
  • This made transport behavior inconsistent and harder to reason about

As a result:

  • Local HTTP usage was insecure by default
  • Browser-based attacks were possible against local gateways
  • Transport behavior was inconsistent across stdio vs HTTP/SSE

How this change fixes it

The gateway transport logic was updated to enforce safe defaults while preserving developer workflows.

Specifically:

  • HTTP-based transports now validate the Origin header

    • Only localhost, 127.0.0.1, and ::1 are allowed
    • Subdomain and DNS rebinding attacks are blocked
  • Requests without an Origin header continue to work

    • CLI tools and SDKs remain fully compatible
  • The stdio transport now runs asynchronously

    • Startup behavior is consistent with HTTP/SSE transports
  • Comprehensive unit tests were added to validate:

    • Origin validation logic

    • Middleware behavior

    • Defense-in-depth with authentication

This preserves security guarantees while restoring a clean and predictable local developer experience.

Before / After (Summary)

Before

  • HTTP transports accepted arbitrary browser origins
  • Potential DNS rebinding and cross-origin vulnerabilities
  • Inconsistent transport lifecycle behavior
  • Local testing did not reflect safe production behavior

After

  • Non-localhost browser origins are explicitly blocked
  • CLI and SDK clients continue to work without changes
  • Transport behavior is consistent across stdio, SSE, and streaming
  • Local testing is secure, deterministic, and trustworthy

@Pnkcaht Pnkcaht requested a review from a team as a code owner January 26, 2026 15:44
Signed-off-by: pnkcaht <samzoovsk19@gmail.com>
@slimslenderslacks
Copy link
Collaborator

@saucow some of these checks are being performed already, right?

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.

Claude Code to MCP Toolkit is timing out.

2 participants