feat(mcp): validate Host/Origin headers on MCP HTTP transports#642
Closed
vishal-bala wants to merge 1 commit into
Closed
feat(mcp): validate Host/Origin headers on MCP HTTP transports#642vishal-bala wants to merge 1 commit into
vishal-bala wants to merge 1 commit into
Conversation
Harden the MCP server's streamable-http and SSE transports by validating the Host and Origin request headers against allowlists before any tool call runs. The guard is on by default and auto-derives a safe allowlist from the bind address, so loopback and local clients work with no config. Non-loopback and reverse-proxy deployments can extend the allowlist (or disable the guard) via a server.transport_security config block and REDISVL_MCP_* environment variables, mirroring the existing auth pattern. stdio has no network surface and is unaffected. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
🛡️ Jit Security Scan Results✅ No security findings were detected in this PR
Security scan by Jit
|
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
RedisVL can expose a configured Redis index to MCP clients over HTTP, through the
streamable-httpandssetransports. Until now, once such a server was listening it would answer any HTTP request that reached its port, without confirming that the request was actually addressed to it. Validating that requests are intended for this server is a standard piece of transport hardening, and one worth having on by default rather than left to each deployment.This change adds that check: the HTTP transports now confirm, on every request, that it is genuinely addressed to this server before any tool runs.
What changed
The server validates the
HostandOriginheaders of each HTTP request against allowlists and rejects anything that doesn't match, before the request reaches the search or upsert tools. The protection is on by default and needs no configuration for the common cases — the allowlist is derived automatically from the address the server binds to, so loopback and same-machine clients keep working exactly as before. Requests that carry noOrigin(typical of non-browser MCP clients) are unaffected; only cross-site origins are scrutinized.For deployments where the client-visible host legitimately differs from the bind address — behind a reverse proxy, or bound to
0.0.0.0and reached by a public hostname — the allowlist can be extended, or the check relaxed, through a newserver.transport_securityblock in the MCP config and matchingREDISVL_MCP_*environment variables. This mirrors the existing authentication configuration, so it should feel familiar. Authentication and this check are complementary and independent: auth decides who may call, while this decides which authority a request may claim. Thestdiotransport has no network surface and is untouched.Implementation notes
redisvl/mcp/transport_security.pymodule holds a small ASGI middleware plus the config resolution, with FastMCP/Starlette imports deferred so the module stays importable without the optionalmcpextra.RedisVLMCPServer.run_async, so it applies to both the CLI and any programmatic embedder, and runs outermost — ahead of auth and the tool handlers.0.0.0.0bind trusts only loopback until the operator names its public hosts.Tests & docs
Adds unit coverage for the middleware (host/origin matching, port and IPv6 handling, case-insensitivity, enable/disable) and for its config resolution, plus integration tests over real HTTP confirming that a legitimate local client still succeeds while spoofed hosts and cross-site origins are rejected. The MCP how-to and authentication guides gain a "Transport Security" section covering the defaults and the configuration knobs.
🤖 Generated with Claude Code