Skip to content

Commit 02d53e3

Browse files
committed
Reject origins except for /tidewave
1 parent 3d230a7 commit 02d53e3

File tree

2 files changed

+27
-0
lines changed

2 files changed

+27
-0
lines changed

lib/tidewave/middleware.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ class Tidewave::Middleware
2020
If you really want to allow remote connections, set `config.tidewave.allow_remote_access = true`.
2121
TEXT
2222

23+
INVALID_ORIGIN = "For security reasons, Tidewave does not accept requests with an origin header for this endpoint.".freeze
24+
2325
def initialize(app, config)
2426
@allow_remote_access = config.allow_remote_access
2527
@client_url = config.client_url
@@ -55,6 +57,7 @@ def call(env)
5557

5658
if path[0] == TIDEWAVE_ROUTE
5759
return forbidden(INVALID_IP) unless valid_client_ip?(request)
60+
return forbidden(INVALID_ORIGIN) if request.get_header("HTTP_ORIGIN") && path != [ TIDEWAVE_ROUTE ]
5861

5962
# The MCP routes are handled downstream by FastMCP
6063
case [ request.request_method, path ]

spec/middleware_spec.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,30 @@ def app
164164
end
165165
end
166166

167+
describe "Origin header validation" do
168+
it "allows requests with Origin header to /tidewave" do
169+
get "/tidewave", {}, { "HTTP_ORIGIN" => "http://example.com" }
170+
expect(last_response.status).to eq(200)
171+
end
172+
173+
it "rejects requests with Origin header to /tidewave/mcp" do
174+
get "/tidewave/mcp", {}, { "HTTP_ORIGIN" => "http://example.com" }
175+
expect(last_response.status).to eq(403)
176+
expect(last_response.body).to include("Tidewave does not accept requests with an origin header for this endpoint")
177+
end
178+
179+
it "rejects requests with Origin header to /tidewave/config" do
180+
get "/tidewave/config", {}, { "HTTP_ORIGIN" => "http://example.com" }
181+
expect(last_response.status).to eq(403)
182+
expect(last_response.body).to include("Tidewave does not accept requests with an origin header for this endpoint")
183+
end
184+
185+
it "allows requests without Origin header to /tidewave/config" do
186+
get "/tidewave/config"
187+
expect(last_response.status).to eq(200)
188+
end
189+
end
190+
167191
describe "edge cases" do
168192
it "handles trailing slashes" do
169193
get "/tidewave/"

0 commit comments

Comments
 (0)