fix: add validation for OAuth redirect URLs

- Create shared validateRedirectUrl utility to centralize URL validation
- Only allow HTTP and HTTPS protocols in OAuth authorization URLs
- Fix three vulnerable redirect paths that bypassed validation:
  - AuthDebugger.tsx: Direct window.location.href redirect
  - OAuthFlowProgress.tsx: window.open() without validation
  - OAuthFlowProgress.tsx: Direct anchor href attribute
- Add comprehensive test coverage for URL validation
- Update existing auth.ts to use shared validation utility

This prevents malicious MCP servers from injecting javascript: or data:
protocol URLs that would execute XSS attacks when users are redirected
to the authorization endpoint.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Jenn Newton 2025-08-15 13:09:49 -04:00
commit 650f3090d2
No known key found for this signature in database

View file

@ -6,6 +6,7 @@ import { AuthDebuggerState, EMPTY_DEBUGGER_STATE } from "../lib/auth-types";
import { OAuthFlowProgress } from "./OAuthFlowProgress";
import { OAuthStateMachine } from "../lib/oauth-state-machine";
import { SESSION_KEYS } from "../lib/constants";
import { validateRedirectUrl } from "@/utils/urlValidation";
export interface AuthDebuggerProps {
serverUrl: string;
@ -163,6 +164,22 @@ const AuthDebugger = ({
currentState.oauthStep === "authorization_code" &&
currentState.authorizationUrl
) {
// Validate the URL before redirecting
try {
validateRedirectUrl(currentState.authorizationUrl);
} catch (error) {
updateAuthState({
...currentState,
isInitiatingAuth: false,
latestError: error instanceof Error ? error : new Error(String(error)),
statusMessage: {
type: "error",
message: `Invalid authorization URL: ${error instanceof Error ? error.message : String(error)}`,
},
});
return;
}
// Store the current auth state before redirecting
sessionStorage.setItem(
SESSION_KEYS.AUTH_DEBUGGER_STATE,