fix(http): add host check#764
Conversation
There was a problem hiding this comment.
Pull request overview
Adds DNS rebinding mitigations to the Streamable HTTP server by validating inbound Host/Origin headers against a configurable allowlist, and introduces an integration test covering allowed vs. blocked host/origin scenarios.
Changes:
- Add
allowed_hoststoStreamableHttpServerConfigwith helpers to configure/disable it. - Enforce
Host/Originvalidation early in request handling, returning403 Forbiddenon violations. - Add an integration test asserting
403for disallowedHostand disallowedOrigin.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| crates/rmcp/src/transport/streamable_http_server/tower.rs | Introduces allowlisted Host/Origin validation for DNS rebinding protection and config knobs to control it. |
| crates/rmcp/tests/test_custom_headers.rs | Adds an integration test to verify Host/Origin enforcement behavior. |
| /// | ||
| /// By default, Streamable HTTP servers only accept loopback hosts to | ||
| /// prevent DNS rebinding attacks against locally running servers. Public | ||
| /// deployments should override this list with their own hostnames. | ||
| pub allowed_hosts: Vec<String>, |
There was a problem hiding this comment.
Adding the new pub allowed_hosts field to StreamableHttpServerConfig is a semver-breaking change for downstream users constructing the config via struct literals (they will now fail to compile). If this is intended, it should be paired with a major version bump / explicit release note; otherwise consider making the config #[non_exhaustive] and/or moving toward a constructor/builder pattern to avoid future breakage.
There was a problem hiding this comment.
This is especially important given that PR #715 was recently merged to prepare for 1.0 stable release. StreamableHttpServerConfig may have been missed in that effort. Adding #[non_exhaustive] here would be consistent with that direction and prevent this class of breakage going forward.
There was a problem hiding this comment.
I think this security update should be introduced in 1.0 version , and I will add the #[non_exhaustive].
| let bad_origin_request = Request::builder() | ||
| .method(Method::POST) | ||
| .header("Accept", "application/json, text/event-stream") | ||
| .header(CONTENT_TYPE, "application/json") | ||
| .header("Host", "localhost:8080") |
There was a problem hiding this comment.
Consider adding a test case for the same-hostname/different-port scenario (e.g., Host: localhost:8080 with Origin: http://localhost:9999) and assert it is rejected. This guards against port-mismatch bypasses of the Host/Origin validation logic.
DaleSeo
left a comment
There was a problem hiding this comment.
Thank you for tackling DNS rebinding protection, @jokemanfire. This is an important security hardening that the MCP Streamable HTTP transport was missing.
I actually implemented a similar Host validation feature on the consumer side in apollographql/apollo-mcp-server#602, so I very much welcome this change. Once this lands in the SDK, I'd love to remove our application-layer middleware and rely on this built-in protection instead.
I have a few suggestions based on what I learned building the consumer-side implementation.
| /// | ||
| /// By default, Streamable HTTP servers only accept loopback hosts to | ||
| /// prevent DNS rebinding attacks against locally running servers. Public | ||
| /// deployments should override this list with their own hostnames. | ||
| pub allowed_hosts: Vec<String>, |
There was a problem hiding this comment.
This is especially important given that PR #715 was recently merged to prepare for 1.0 stable release. StreamableHttpServerConfig may have been missed in that effort. Adding #[non_exhaustive] here would be consistent with that direction and prevent this class of breakage going forward.
1b06803 to
d25647e
Compare
This is a security problem ,there is a lack of host access verification here, which may be exploited by malicious attacks.
Motivation and Context
Adds Host validation to the Streamable HTTP server to mitigate DNS rebinding risks. Introduces configurable allowed hosts, and adds integration tests for both valid localhost traffic and malicious request scenarios.
How Has This Been Tested?
Add the it test
Breaking Changes
Yes, the sec change may change the mcp's server feature which has been deployed.
Types of changes
Checklist
Additional context