Hmbown/CodeWhale · error
MCP SSE endpoint {} is not same-origin as {} — refusing to s
Error message
MCP SSE endpoint {} is not same-origin as {} — refusing to send authenticated requests cross-origin What it means
Security guard: the endpoint event's URL resolved to a different origin (scheme, host, or port) than the connect URL. Because authenticated POSTs (Bearer/OAuth headers) target that endpoint, a cross-origin value would let a malicious MCP server redirect the client's credentials at internal hosts (169.254.169.254, localhost admin ports) — an SSRF/policy bypass. Relative endpoints are same-origin by construction and always pass.
Source
Thrown at crates/tui/src/mcp/sse.rs:260
let base = reqwest::Url::parse(base_url)?;
let resolved =
if endpoint_url.starts_with("http://") || endpoint_url.starts_with("https://") {
reqwest::Url::parse(endpoint_url)?
} else {
base.join(endpoint_url)?
};
// Security: the server-supplied `endpoint` event must stay same-origin
// as the connect URL. The connect host is vetted by network policy
// once, but the endpoint host is never re-checked — so an absolute
// cross-origin endpoint would let a malicious MCP server redirect the
// client's *authenticated* POSTs (Bearer/OAuth headers attached) to an
// internal host (169.254.169.254, localhost admin ports, …): an SSRF /
// policy bypass. Relative endpoints are same-origin by construction.
if resolved.scheme() != base.scheme()
|| resolved.host_str() != base.host_str()
|| resolved.port_or_known_default() != base.port_or_known_default()
{
anyhow::bail!(
"MCP SSE endpoint {} is not same-origin as {} — refusing to send \
authenticated requests cross-origin",
mask_url_secrets(resolved.as_str()),
mask_url_secrets(base.as_str()),
);
}
Ok(resolved.to_string())
}
}
#[async_trait::async_trait]
impl McpTransport for SseTransport {
async fn send(&mut self, msg: Vec<u8>) -> Result<()> {
let endpoint = self
.endpoint_url
.as_ref()
.context("SSE endpoint not yet discovered")?
.clone();View on GitHub (pinned to 8880682c63)
Solutions
- Fix the server to send a relative endpoint path (e.g. /messages?sessionId=...) or an absolute URL with the same scheme, host, and port as the connect URL
- If the server legitimately moved, change the configured MCP server URL to the new origin rather than the endpoint event
- Treat unexpected cross-origin endpoints as a security finding in the server, never as a client bug to bypass
Defensive patterns
Strategy: try-catch
Type guard
```rust
fn is_cross_origin_refusal(err: &anyhow::Error) -> bool {
format!("{err:#}").contains("is not same-origin as")
}
``` Try / catch
```rust
Err(e) if is_cross_origin_refusal(&e) => {
// Security: the server tried to redirect authenticated POSTs off-origin.
report_untrusted_server(&server_name, &e); // never bypass; surface prominently
return Err(e);
}
``` Prevention
- Prefer MCP servers that advertise relative endpoint paths
- Never relax the same-origin check; treat trips as a finding against the server and report to its operator
When it happens
Trigger: The server sends `event: endpoint` with an absolute URL on another origin — e.g. connect to https://mcp.example.com but endpoint data: http://169.254.169.254/latest or http://127.0.0.1:8081/messages.
Common situations: Misconfigured server advertising an internal or admin origin; load balancers rewriting the advertised endpoint to a different host/port; genuinely malicious servers probing for SSRF.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- MCP config path cannot contain '..' components
- reviewed plugin stage could not be opened for launch
- reviewed plugin stdio cwd escaped its staged root
- Refusing to {operation} MCP server '{server_name}' from plug
- Refusing MCP server '{server_name}': its remote endpoint no
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/53b937d81bc93bc4.
Report an issue: GitHub.