# `ConduitMcp.Plugs.OriginValidation`
[🔗](https://github.com/nyo16/conduit_mcp/blob/v0.10.1/lib/conduit_mcp/plugs/origin_validation.ex#L1)

Plug that validates the `Origin` request header against an allowlist.

Reads the allowlist from `conn.private[:allowed_origins]`. Behavior:

- `nil` or `"*"` — no restriction, all origins allowed
- A list of strings — only those origins are allowed
- OPTIONS requests always pass (CORS preflight)
- Requests without an `Origin` header pass (browser-less clients don't send it)
- Disallowed origins receive a 403 JSON error response

## Why missing `Origin` passes

Native MCP clients (Claude Desktop, IDEs, CLIs) are not browsers and do not
send an `Origin` header. The attack this plug defends against — DNS
rebinding — requires a browser, and browsers always attach `Origin` to
cross-origin requests. Rejecting header-less requests would therefore break
every legitimate non-browser client without adding protection.

The MCP specification recommends Origin validation for any server a browser
could reach (especially servers bound to loopback on developer machines).
Transports log a startup warning when `:allowed_origins` is unset; pass
`allowed_origins: "*"` to acknowledge and silence it.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
