[Plugin] Fix Windows OAuth sign-in: authorize URL truncated by cmd.exe (invalid_client) - #37
Merged
eshwar-sundar-glean merged 2 commits intoJul 15, 2026
Conversation
openBrowser() launched the authorize URL via 'cmd /c start'. cmd.exe treats the unquoted '&' between OAuth query params as a command separator, truncating the URL at '?response_type=code' and dropping client_id, so the server rejects sign-in with invalid_client. Windows only; macOS/Linux use execFile and are unaffected. Launch via explorer.exe (no shell) so the full URL reaches the browser intact.
steve-calvert-glean
requested review from
eshwar-sundar-glean,
garvit-scio,
mohit-gupta-glean and
swarup-padhi-glean
as code owners
July 14, 2026 21:57
Collaborator
|
this solution does not work on windows, tested it, it opens file explorer |
explorer.exe is the Windows shell, not a reliable URL launcher: it only sometimes forwards an http(s) argument to the default browser and otherwise opens a File Explorer window, so OAuth sign-in never reached the browser. Route back through `cmd /c start` (which resolves the http protocol to the default browser) but escape every `&` as `^&` and pass args verbatim so Node doesn't re-quote and neutralize the `^`. cmd then un-escapes `^&` to a literal `&`, so it no longer treats `&` as a command separator and truncates the authorize URL at the first param -- which had dropped client_id and triggered invalid_client. Update the openBrowser Windows unit test accordingly.
Collaborator
|
Pushed a fix and tested it on windows |
eshwar-sundar-glean
approved these changes
Jul 15, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
On Windows, the plugin's OAuth sign-in fails immediately with
invalid_client/ "The requested OAuth 2.0 Client does not exist", even though Dynamic Client Registration succeeds. Root cause isopenBrowser()launching the authorize URL throughcmd /c start.Root cause
The MCP SDK builds the authorize URL with
response_typefirst, thenclient_idand the rest, joined by&:openBrowser()passed this tospawn("cmd", ["/c", "start", "", url]). Node only quotes an argv element on Windows if it contains a space/tab (or is empty); the URL has neither, so it reachescmd.exeunquoted.cmd.exetreats&as a command separator, so it launches only:and everything after the first
&(client_id, redirect_uri, PKCE, state) is dropped. The browser opens a URL with noclient_id, and the server correctly rejects it asinvalid_client.Observed on an affected tenant: the load-balancer log shows the browser requesting exactly
GET /oauth/authorize?response_type=code(truncated at the first&), immediately after a successfulPOST /oauth/register(201). macOS/Linux are unaffected because they useexecFile("open"/"xdg-open", [url]), which passes the URL as a single argv element with no shell.Fix
Eshwar - Prefer CMD for now as that was the only approach I was able to test
Launch the URL via
explorer.exeinstead ofcmd /c start.explorer.exeopens the default browser and receives the URL as a single argv element with no shell, so&and percent-encoded characters survive intact.Chose
explorer.exeoverrundll32 url.dll,FileProtocolHandler(also cmd-free) becauserundll32is a common LOLBin frequently blocked by enterprise EDR/AppLocker, and the affected users are on managed corporate Windows. Keptcmdout of the path entirely rather than escaping&/%, which is fragile (percent-encoded values such asredirect_uri=http%3A%2F%2F...can also tripcmdvariable expansion).Testing
tests/open-browser.test.ts: asserts the Windows launcher is notcmd, the full URL (including everything after the first&) is passed as one argument, and macOS/Linux behavior is unchanged.npx vitest run— 26 passed (3 new + 23 existing auth-provider tests).npx tsc --noEmit— clean.Please verify before merge
I validated via unit test + typecheck on macOS. Needs a manual smoke test on a real Windows machine: run the plugin sign-in and confirm the browser opens the full
?response_type=code&client_id=...URL and OAuth completes.