Skip to content

[v1.x] fix(auth): reject non-loopback http and fragment redirect URIs at registration - #3143

Open
samuelmbabhazi wants to merge 1 commit into
modelcontextprotocol:v1.xfrom
samuelmbabhazi:fix/register-redirect-uri-validation
Open

samuelmbabhazi wants to merge 1 commit into
modelcontextprotocol:v1.xfrom
samuelmbabhazi:fix/register-redirect-uri-validation

Conversation

@samuelmbabhazi

Copy link
Copy Markdown

Fixes #3142.

The registration handler of mcpAuthRouter validated redirect_uris only with SafeUrlSchema, so it registered http://attacker.example.com/callback and https://client.example.com/callback#fragment with 201. The spec requires HTTPS or a loopback host for redirect URIs (Communication Security), and RFC 6749 §3.1.2 forbids a fragment.

The handler now answers both with 400 invalid_client_metadata. That is the response hosting:auth:as:redirect-uri-scheme in test/e2e/requirements.ts already expected, so this removes its known failure, and the scenario now also registers a URI with a fragment.

  • The check lives in the handler, not in OAuthClientMetadataSchema, which clients also use to parse metadata.
  • Loopback means the hosts the authorize handler already relaxes ports for (localhost, 127.0.0.1, [::1]), so LOOPBACK_HOSTS is exported from authorize.ts and reused rather than defined twice.
  • Private-use schemes such as com.example.app:/callback are still accepted. No new option.

The changeset says what breaks: re-registering a non-loopback http: or fragment URI now fails, existing registrations are untouched.

Unit tests in register.test.ts cover the rejected cases, loopback http: on any port, and a private-use scheme. Without the change, the two rejection tests fail and the e2e scenario fails once the known failure is removed.

…istration

The registration handler validated redirect_uris only with SafeUrlSchema, so
it registered http://attacker.example.com/callback and URIs with a fragment.
The MCP authorization spec requires HTTPS or a loopback host, and RFC 6749
§3.1.2 forbids a fragment. Both now get 400 invalid_client_metadata, which is
what the hosting:auth:as:redirect-uri-scheme requirement already expected, so
its known failure is removed and the scenario also covers a fragment.

The loopback hosts are the ones the authorize handler already relaxes ports
for (localhost, 127.0.0.1, [::1]). Private-use schemes stay accepted.

Fixes modelcontextprotocol#3142
@samuelmbabhazi
samuelmbabhazi requested review from a team as code owners November 1, 2026 19:18
@changeset-bot

changeset-bot Bot commented Nov 1, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: b65b1ae

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented Nov 1, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@modelcontextprotocol/sdk@3143

commit: b65b1ae

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

v1 Issues / PRs related to v1.x

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant