From 463b3369419af1f67698f8a1f27d1248240347fd Mon Sep 17 00:00:00 2001 From: Jeremiah Lowin <153965+jlowin@users.noreply.github.com> Date: Wed, 29 Oct 2025 11:04:56 -0700 Subject: [PATCH] Fix Chrome CSP blocking OAuth consent form with custom protocol redirects (#2305) * Fix Chrome CSP blocking OAuth consent form with custom protocol redirects * Fix Chrome CSP blocking OAuth consent form with custom protocol redirects Dynamically include custom protocol schemes in CSP form-action directive when redirect URIs use custom protocols like cursor:// --- src/fastmcp/server/auth/oauth_proxy.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/fastmcp/server/auth/oauth_proxy.py b/src/fastmcp/server/auth/oauth_proxy.py index 2d7dd6472..6f1336d96 100644 --- a/src/fastmcp/server/auth/oauth_proxy.py +++ b/src/fastmcp/server/auth/oauth_proxy.py @@ -365,7 +365,19 @@ def create_consent_html( ) # Need to allow form-action for form submission - csp_policy = "default-src 'none'; style-src 'unsafe-inline'; img-src https:; base-uri 'none'; form-action *" + # Chrome requires explicit scheme declarations in CSP form-action when redirect chains + # end in custom protocol schemes (e.g., cursor://). Parse redirect_uri to include its scheme. + parsed_redirect = urlparse(redirect_uri) + redirect_scheme = parsed_redirect.scheme.lower() + + # Build form-action directive with standard schemes plus custom protocol if present + form_action_schemes = ["https:", "http:"] + if redirect_scheme and redirect_scheme not in ("http", "https"): + # Custom protocol scheme (e.g., cursor:, vscode:, etc.) + form_action_schemes.append(f"{redirect_scheme}:") + + form_action_directive = " ".join(form_action_schemes) + csp_policy = f"default-src 'none'; style-src 'unsafe-inline'; img-src https:; base-uri 'none'; form-action {form_action_directive}" return create_page( content=content,