fix(mcp): allow loopback redirect_uri with any port per RFC 8252#1824
fix(mcp): allow loopback redirect_uri with any port per RFC 8252#1824yusukebe merged 5 commits intohonojs:mainfrom
Conversation
The authorize handler does strict string matching on redirect_uris, rejecting localhost callbacks with ephemeral ports (e.g. localhost:58621/callback) when the client registered localhost/callback without a port. Per RFC 8252 Section 7.3, loopback redirect URIs should match on scheme+host+path only, ignoring port. This adds an isLoopbackRedirectAllowed() check for localhost, 127.0.0.1, and [::1]. Non-loopback URIs still use strict matching.
🦋 Changeset detectedLatest commit: dfddd05 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
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 |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1824 +/- ##
==========================================
- Coverage 91.73% 91.71% -0.02%
==========================================
Files 113 113
Lines 3785 3803 +18
Branches 957 964 +7
==========================================
+ Hits 3472 3488 +16
- Misses 281 283 +2
Partials 32 32
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
Hey @MathurAditya724 , Can you reivew this? |
MathurAditya724
left a comment
There was a problem hiding this comment.
Looks good 🔥, just a minor change and then we can merge it
Addresses review feedback to also compare req.search in isLoopbackRedirectAllowed, preventing loopback URIs with extra query parameters from bypassing validation.
|
@arjunkmrm @MathurAditya724 Thank you! |
We ran into this while running Smithery as an MCP OAuth proxy using
@hono/mcp. Claude Code registershttp://localhost/callbackin its client metadata but connects with an ephemeral port at runtime (e.g.http://localhost:58621/callback). The authorize handler rejects it becauseredirect_uris.includes()does a strict string comparison.RFC 8252 Section 7.3 says loopback redirect URIs should match on scheme + host + path only, ignoring the port — native OAuth clients pick a random available port each time. Here's the excerpt:
This adds a small
isLoopbackRedirectAllowed()helper that kicks in only forlocalhost,127.0.0.1, and[::1]. Everything else still uses strict matching. Four new tests cover the happy path, path mismatch rejection, and non-loopback strictness.Fixes #1823
The author should do the following, if applicable
yarn changesetat the top of this repo and push the changeset