createmcps.com

Error

MCP server and the Origin header: DNS rebinding, and the 403 you should be sending

Against MCP 2026-07-28 · verified 10 August 2026

This is the reverse of most entries here: the problem is not an error you received, it is an error your server failed to send. A request arrived from an origin it does not know, and it answered normally.

The error

Accepted a request with an unrecognised Origin
How often we see this:

1 of the 16 real MCP servers we probed on 2026-08-11 tripped MCP-SEC-001. That is a snapshot of hand-picked public servers, not a random sample of the ecosystem — it shows the failure is common in practice, not that a given percentage of all servers have it.

What causes it

An MCP server listening on HTTP is reachable by any web page the user visits, subject to the browser's rules. DNS rebinding defeats those rules: an attacker's page resolves its own hostname to your server's address, so the browser believes it is talking to the attacker's origin and sends the request anyway.

The defence is the `Origin` header, which the browser sets and a page cannot forge. A server that validates it and rejects unknown values with 403 is safe from this class of attack. A server that ignores it is reachable by any page the user happens to open — and if it is bound to localhost for local development, that is a particularly soft target.

This matters more for MCP than for a typical API because MCP servers are frequently given real authority: file access, internal services, credentials. The ecosystem's baseline here is poor, which is precisely why the specification makes it a MUST.

How to fix it

The fix

Validate Origin on every request, and default to refusingCompare against an explicit allowlist. An absent Origin (a non-browser client) is fine to accept; an Origin that is present and unrecognised must be refused. Allowing anything you do not recognise is the same as not checking.
Origin validation, refusing by default
const ALLOWED = new Set([
  "https://claude.ai",
  "http://localhost:3000",
]);

const origin = request.headers.get("origin");
// No Origin at all: not a browser. Present but unknown: refuse.
if (origin !== null && !ALLOWED.has(origin)) {
  return new Response("Forbidden", { status: 403 });
}

The fix

Bind local servers to 127.0.0.1, not 0.0.0.0A development server on 0.0.0.0 is reachable from the whole local network, not just the machine. This does not replace Origin validation — rebinding attacks come through the browser on the same machine — but it removes an entire second route in.

The fix

Do not accept Origin as authenticationOrigin says which page made the request; it says nothing about who the user is. It is a defence against a browser being used as a confused deputy, and it belongs alongside real authorization, not instead of it.

Rules involved

Each of these is checked against a live server, and each links to the exact sentence of the specification it comes from.

RuleWhat we checkLevelIf it fails
MCP-SEC-001Invalid Origin header returns HTTP 403MUSTfail
MCP-SEC-002Endpoint is HTTPS with a valid, unexpired certificate chainMAYfail

FAQ

Frequently asked

Does an MCP server have to validate the Origin header?

Yes. The specification makes it a MUST: servers validate Origin and reject an unrecognised one with 403. It is the defence against DNS rebinding, where an attacker's web page causes a browser to send requests to a server it should not be able to reach.

What is DNS rebinding, and why does it affect MCP servers?

An attacker's page resolves its own hostname to your server's IP address, so the browser treats requests to your server as same-origin with the attacker's page and sends them. It affects MCP servers disproportionately because they are often local, often unauthenticated, and often hold real authority over files or internal services.

What should I do when there is no Origin header at all?

Accept it. A missing Origin means the request did not come from a browser, and a non-browser client is not the threat model this control addresses. The rule is about an Origin that is present and unrecognised.

Check this against your own server

Point the validator at a live MCP server and it reports every rule on this page as pass, warn or fail — each linked to the exact spec sentence it comes from.

Validate a server →