[Bug Fix] MCP: allow rubyui.com host in DNS-rebinding protection - #491
Open
djalmaaraujo wants to merge 1 commit into
Open
[Bug Fix] MCP: allow rubyui.com host in DNS-rebinding protection#491djalmaaraujo wants to merge 1 commit into
djalmaaraujo wants to merge 1 commit into
Conversation
StreamableHTTPTransport's DNS-rebinding protection only allows loopback Host headers (127.0.0.1, ::1, localhost) by default, so every request to https://rubyui.com/mcp was rejected with "Forbidden: Invalid Host header". RackApp never passed allowed_hosts:, so production traffic never had a chance to pass validation. Pass allowed_hosts: with rubyui.com and www.rubyui.com (overridable via RUBY_UI_MCP_ALLOWED_HOSTS), and add rack_app_test.rb covering both allowed hosts, the loopback default, and that an unrelated host is still rejected. Fixes #481
cirdes
approved these changes
Jul 28, 2026
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.
Fixes #481
Root cause
The remote MCP endpoint at
https://rubyui.com/mcp(andwww.rubyui.com/mcp) rejected every JSON-RPC request with:RubyUI::MCP::RackApp#initialize(mcp/lib/ruby_ui/mcp/rack_app.rb) buildsMCP::Server::Transports::StreamableHTTPTransport(from the third-partymcpgem) without anallowed_hosts:argument. That transport has built-in DNS-rebinding protection: it validates the incomingHostheader against an allow list that defaults to loopback only (127.0.0.1,::1,localhost). Sincerubyui.comwas never on that list, every real request got rejected byvalidate_host.This is unrelated to Rails' own
HostAuthorizationmiddleware /config.hosts— that's commented out indocs/config/environments/production.rband isn't the cause; the rejection happens entirely inside themcpgem's transport.Fix
RubyUI::MCP::RackAppnow passesallowed_hosts: ["rubyui.com", "www.rubyui.com"](plus the transport's own loopback defaults) when constructing the transport, extendable via a comma-separatedRUBY_UI_MCP_ALLOWED_HOSTSenv var — same pattern already used forRUBY_UI_MCP_REGISTRYinmcp/lib/ruby_ui/mcp/registry.rb.allowed_origins:was not touched: the transport treats a request as same-origin (and thus allowed) wheneverOriginmatchesHost, and non-browser MCP clients typically send noOriginheader at all, so onceHostis allow-listed the existing same-origin check already covers browser-based clients hittingrubyui.com/www.rubyui.com.Second sub-problem (redirect)
The issue also reports
https://rubyui.com/mcp301-redirecting tohttps://www.rubyui.com/mcp, tripping up some MCP clients mid-handshake. I searcheddocs/config,docs/app/controllers,docs/config/routes.rb, anddocs/Procfileand found no www-redirect logic, middleware, or infra config files (no_redirects,render.yaml, Cloudflare config, etc.) anywhere in the repo.config.force_ssl = trueforces HTTPS only, not a www redirect. This redirect is happening at the Cloudflare/Render layer in front of the app, outside this repo — flagging as a known limitation/follow-up for whoever manages that infra config. This PR's fix does make it less harmful in the meantime: bothrubyui.comandwww.rubyui.comare now allow-listed, so a client that does follow the redirect will succeed on the second hop instead of failing onHostvalidation either way.Test plan
mcp/test/rack_app_test.rb: asserts requests withHost: rubyui.com,Host: www.rubyui.com, andHost: localhostare not rejected with "Invalid Host header", assertsHost: evil.example.comis still rejected (DNS-rebinding protection intact), and covers theRUBY_UI_MCP_ALLOWED_HOSTSenv override.cd mcp && bundle exec rake test— 30 runs, 73 assertions, 0 failures, 0 errors, 0 skips.cd mcp && bundle exec standardrb lib/ruby_ui/mcp/rack_app.rb test/rack_app_test.rb— clean, no offenses. (Note:bundle exec rake standardacross the wholemcp/tree currently reports pre-existing offenses in unrelated files —mcp/has no committedGemfile.lock, sobundle installresolved newerstandard/rubocopversions than whatever last verified the tree; unrelated to this change.)docs/was not touched:/mcprouting itself doesn't change, so noSiteFiles/site_files:generateupdate is needed.docsdepends onruby_ui-mcpviapath: "../mcp", so this fix ships with the next docs deploy without any version bump or gem republish.Summary by cubic
Fixes “Invalid Host header” errors on the MCP endpoint by allow-listing production hosts while keeping DNS-rebinding protection intact. Requests to
https://rubyui.com/mcpandhttps://www.rubyui.com/mcpnow work.allowed_hoststoStreamableHTTPTransportwith["rubyui.com", "www.rubyui.com"], extendable viaRUBY_UI_MCP_ALLOWED_HOSTS.Written for commit 520d07d. Summary will update on new commits.