-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Fix: OAuth CORS errors when Connection Type is 'Via Proxy' #996
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Fix: OAuth CORS errors when Connection Type is 'Via Proxy' #996
Conversation
|
@cliffhall PTAL 🙏 |
|
Claude encountered an error —— View job I'll analyze this and get back to you. |
|
Just want to chime in and say I pulled down the branch and it worked. Immediately clicking "Connect" fails (I think this is a separate issue), but clicking "Quick OAuth Flow" successfully registers the client via DCR and authenticates the user. After that, the token is acquired and "Connect" now works, and I can interact with the MCP server normally. @asoorm Thanks for finding this and submitting the fix. Look forward to seeing it merged. |
|
@claude /review |
|
Claude finished @cliffhall's task in 3m 5s —— View job PR Review: Fix OAuth CORS errors when Connection Type is 'Via Proxy'Tasks
SummaryThis PR successfully addresses OAuth CORS issues when using proxy connection type by routing all OAuth operations through the Express proxy server. The implementation is well-structured and follows existing patterns. The code has been tested successfully with Keycloak (confirmed by @anthonychu). However, there are several areas that need attention before merging. Review Details✅ Strengths
🔴 Critical Issues1. Server-Side Input Validation Issues (Security)Location: The server endpoints only check if parameters exist but don't validate their format or content: // Current - only checks existence
const authServerUrl = req.query.authServerUrl as string;
if (!authServerUrl) {
res.status(400).json({ error: "authServerUrl query parameter is required" });
return;
}Issues:
Recommendation: Add URL validation to ensure only HTTP/HTTPS URLs are accepted and optionally allowlist domains: const authServerUrl = req.query.authServerUrl as string;
if (!authServerUrl) {
res.status(400).json({ error: "authServerUrl query parameter is required" });
return;
}
try {
const url = new URL(authServerUrl);
if (!['http:', 'https:'].includes(url.protocol)) {
res.status(400).json({ error: "Only HTTP/HTTPS URLs are allowed" });
return;
}
// Optional: Add domain allowlist check here
} catch (e) {
res.status(400).json({ error: "Invalid URL format" });
return;
}2. Incorrect express.json() Placement (Bug)Location: // OAuth Proxy Endpoints - for routing OAuth requests through the proxy to avoid CORS issues
app.use(express.json()); // Ensure JSON body parsing is enabledIssue: This middleware is placed after the Recommendation: Move 3. Missing Error Types/Codes (Usability)Location: All proxy functions in The error handling is basic and doesn't distinguish between different types of failures: if (!response.ok) {
const error = await response.json().catch(() => ({ error: response.statusText }));
throw new Error(`Failed to discover OAuth metadata: ${error.error || response.statusText}`);
}Issue: Users get generic error messages that don't help them diagnose network issues, authentication failures, or CORS problems. Recommendation: Add more specific error handling:
|
@anthonychu verified this.
|
12e46c1 to
ac12e62
Compare
- Add GET /oauth/metadata for authorization server metadata discovery - Add GET /oauth/resource-metadata for protected resource metadata - Add POST /oauth/register for Dynamic Client Registration (DCR) - Add POST /oauth/token for token exchange - All endpoints use existing auth middleware and origin validation - Properly handle URL construction for different OAuth server types
- Create discoverAuthorizationServerMetadataViaProxy() - Create discoverOAuthProtectedResourceMetadataViaProxy() - Create registerClientViaProxy() for DCR - Create exchangeAuthorizationViaProxy() for token exchange - Reuse getMCPProxyAddress() and getMCPProxyAuthToken() for consistency - Provide clear error messages for debugging
- Update OAuthStateMachine to accept connectionType and config parameters - Conditionally route OAuth operations through proxy when connectionType is 'proxy' - Pass connectionType and config from App.tsx through AuthDebugger to state machine - Fix auth.ts to make scope optional per RFC 7591 - Maintain backward compatibility with direct connections - Follow same pattern as existing MCP server proxy connections
ac12e62 to
496e3c5
Compare
496e3c5 to
8fc3fa6
Compare
- Provide user-friendly error messages based on HTTP status codes - Fix middleware placement for JSON body parsing - Update tests for new error message format
8fc3fa6 to
bbdd582
Compare
|
@cliffhall please take another look - I've implemented recommendations from Claude's review. SSRF validation is intentionally not implemented in the OAuth proxy endpoints. Rationale:
If SSRF protection is deemed necessary for MCP Inspector's threat model, I |
Problem
When users select "Via Proxy" as the Connection Type, OAuth authentication fails with CORS errors because OAuth operations bypass the proxy and execute directly from the browser.
Fixes #995
Solution
Route all OAuth operations through the Express proxy server when connectionType is "proxy", following the same pattern as MCP server connections.
Changes
Server-Side (
server/src/index.ts)Added 4 OAuth proxy endpoints:
GET /oauth/metadata- Authorization server metadata discoveryGET /oauth/resource-metadata- Protected resource metadata discoveryPOST /oauth/register- Dynamic Client Registration (DCR)POST /oauth/token- Token exchangeClient-Side
client/src/lib/oauth-proxy.ts(new) - Proxy utility functionsclient/src/lib/oauth-state-machine.ts- Conditional routing based on connectionTypeclient/src/components/AuthDebugger.tsx- Accepts connectionType/config propsclient/src/App.tsx- Provides connectionType and configclient/src/lib/auth.ts- Fix scope to be optional per RFC 7591Testing
Tested successfully with Keycloak OAuth server. All OAuth operations work without CORS errors in proxy mode. Direct mode still functions for servers with proper CORS configuration.
Backward Compatibility
No breaking changes. Direct connections work as before. Proxy mode is opt-in via existing "Connection Type" selector.
Next Steps
Based on your feedback to this PR, I will add polish, tests, and documentation accordingly.