Skip to content

Add Host header validation to prevent DNS rebinding attacks - #602

Merged
DaleSeo merged 3 commits into
mainfrom
AMS-196
Feb 3, 2026
Merged

DaleSeo merged 3 commits into
mainfrom
AMS-196

Conversation

@DaleSeo

@DaleSeo DaleSeo commented Jan 28, 2026

Copy link
Copy Markdown
Member

This PR addresses a reported DNS rebinding vulnerability. The MCP server was vulnerable because it didn't validate the Host header on incoming HTTP requests, allowing attackers to manipulate the server via DNS rebinding. This PR adds Host header validation middleware that rejects requests with unexpected Host headers, returning 403 Forbidden. The protection is enabled by default for StreamableHttp transport and validates against localhost values with port matching. Custom hosts can be configured via host_validation.allowed_hosts for deployments behind reverse proxies.

transport:
  type: streamable_http
  port: 8000
  host_validation:
    enabled: true  # default
    allowed_hosts:
      - mcp.example.com  # optional

Testing

Start the server:

cargo run -- graphql/TheSpaceDevs/config.yaml

Invalid requests (should return 403 Forbidden)

Attacker domain:

$ curl -i http://localhost:8000/mcp -X POST \
  -H "Host: attacker.com" \
  -H "Accept: application/json, text/event-stream" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"initialize","id":1,"params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'
HTTP/1.1 403 Forbidden
content-type: text/plain
content-length: 30
date: Mon, 02 Feb 2026 16:08:39 GMT

Forbidden: Invalid Host header%

Wrong port:

$ curl -i http://localhost:8000/mcp -X POST \
  -H "Host: localhost:9999" \
  -H "Accept: application/json, text/event-stream" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"initialize","id":1,"params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'
HTTP/1.1 403 Forbidden
content-type: text/plain
content-length: 30
date: Mon, 02 Feb 2026 16:10:00 GMT

Forbidden: Invalid Host header

Valid requests (should return 200):

$ curl -i http://localhost:8000/mcp -X POST \
  -H "Host: localhost:8000" \
  -H "Accept: application/json, text/event-stream" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"initialize","id":1,"params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'
HTTP/1.1 200 OK
content-type: text/event-stream
cache-control: no-cache
mcp-session-id: c2a32a2e-f913-4748-9f71-3ceccb5f7f51
vary: origin, access-control-request-method, access-control-request-headers
access-control-allow-origin: *
access-control-expose-headers: mcp-session-id,traceparent,tracestate
traceparent: 00-d6ab8eb9412feddb0045df809afb02b2-a484986a31e4b1bd-01
tracestate:
transfer-encoding: chunked
date: Mon, 02 Feb 2026 16:10:52 GMT

data:
id: 0
retry: 3000

data: {"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2025-03-26","capabilities":{"tools":{"listChanged":true}},"serverInfo":{"name":"Apollo MCP Server","title":"Apollo MCP Server","version":"1.6.0","websiteUrl":"https://www.apollographql.com/docs/apollo-mcp-server"}}}

@DaleSeo DaleSeo self-assigned this Jan 28, 2026
@apollo-librarian

apollo-librarian Bot commented Jan 28, 2026

Copy link
Copy Markdown
Contributor

✅ Docs preview ready

The preview is ready to be viewed. View the preview

File Changes

0 new, 1 changed, 0 removed
* (developer-tools)/apollo-mcp-server/(latest)/config-file.mdx

Build ID: 421610d537da244ff421f5d0
Build Logs: View logs

URL: https://www.apollographql.com/docs/deploy-preview/421610d537da244ff421f5d0

@DaleSeo
DaleSeo marked this pull request as ready for review January 28, 2026 19:00
@DaleSeo
DaleSeo requested review from a team as code owners January 28, 2026 19:00
@github-actions

Copy link
Copy Markdown
Contributor

Changeset file added - thank you!

@claude

claude Bot commented Jan 28, 2026

Copy link
Copy Markdown

Review Summary

This PR adds Host header validation middleware to mitigate DNS rebinding attacks (GHSA-fv85-8h22-h4rg). The implementation validates incoming Host headers against localhost variants (with port matching) and configurable custom hosts, returning 403 Forbidden for invalid requests.

Findings: No blocking issues found.

  • The implementation correctly addresses the security vulnerability
  • Good use of Cow<str> to avoid allocations in the common case (line 111-124)
  • Arc<HostValidationConfig> appropriately avoids cloning the Vec<String> on each request
  • #[must_use] properly applied to disabled() constructor

Test Coverage Assessment: Excellent. The test suite covers:

  • Localhost variants (localhost, 127.0.0.1, [::1], 0.0.0.0)
  • Port validation for localhost requests
  • Custom allowed hosts (with and without port specifications)
  • Case-insensitive hostname matching
  • Disabled mode behavior
  • Rejection of attacker-controlled hosts

Documentation: The config-file.mdx updates clearly explain the new host_validation configuration options.

Final Recommendation: ✅ Approve


Reviewed by Claude Code Opus 4.5

@gocamille gocamille left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for this @DaleSeo ! 🚢

@sudocurse sudocurse left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @DaleSeo, this looks good.

@DaleSeo
DaleSeo merged commit 8889741 into main Feb 3, 2026
17 checks passed
@DaleSeo
DaleSeo deleted the AMS-196 branch February 3, 2026 13:55
@DaleSeo DaleSeo mentioned this pull request Feb 12, 2026
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.

3 participants