Skip to content

Port relevant commits from 2.9.0 and 2.9.1 releases#2382

Merged
mjcheetham merged 3 commits into
vnextfrom
sec-release-2.9.0_vnextport
Jul 15, 2026
Merged

Port relevant commits from 2.9.0 and 2.9.1 releases#2382
mjcheetham merged 3 commits into
vnextfrom
sec-release-2.9.0_vnextport

Conversation

@mjcheetham

@mjcheetham mjcheetham commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

This is a port of commits from the 2.9.0 and 2.9.1 embargoed releases into the vnext branch.

Note that not all of the commits were required since vnext already had some of the bug fixes (the CFS release change), or have been superseded by refactoring (MicrosoftAuthentication -> EntraAuthentication already changed how we use redirect URIs and resolved auth flows) and updates to even newer MSAL versions.

The authorization code flow only handled the default 'query' response
mode, where the loopback browser reads the response from the request
query string and returns a URI for the client to parse. The 'fragment'
and 'form_post' modes deliver the response over channels a URI cannot
represent - the fragment is never transmitted to the server, and
form_post arrives as a urlencoded POST body - so hosts that mandate
those modes could not be used.

Have the browser return the parsed response parameters regardless of
transport and tell it which mode to expect. The system browser reads
the POST body for form_post, and for fragment serves a small page that
re-submits the parameters as a form POST to the loopback redirect -
keeping the authorization code out of the URL, browser history, and
server logs. The client sends 'response_mode' only when it is not the
default, so existing query-mode requests are unchanged.

Assisted-by: Claude Opus 4.8
Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com>
@mjcheetham mjcheetham requested a review from dscho July 14, 2026 17:16
@mjcheetham mjcheetham requested a review from a team as a code owner July 14, 2026 17:16
@mjcheetham mjcheetham added the gcm3.0 Targets the next major release of Git Credential Manager - v3.0 label Jul 14, 2026
Now that the OAuth client can request non-query response modes, expose
the choice to generic host configurations through a new optional
setting (credential.<host>.oauthResponseMode, or the
GCM_OAUTH_RESPONSE_MODE environment variable). The built-in providers
target known hosts that use 'query', so the generic provider is the
only place an arbitrary host's response mode needs to be configurable.

The setting is optional and defaults to 'query', so existing
configurations are unaffected. An unrecognised value is traced and
falls back to the default rather than failing configuration outright.

Assisted-by: Claude Opus 4.8
Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com>
GCM launches the system browser for interactive OAuth by handing the
authorization URL to the OS "shell execute" handler. On macOS that is
/usr/bin/open, which validates the URL and, on finding any character
that is not legal in a fully percent-encoded URL, re-encodes the whole
query string. That step double-escapes parameters we had already
encoded -- redirect_uri=http%3A%2F%2F... becomes
redirect_uri=http%253A%252F%252F... -- and the authorization server
rejects the redirect. Windows ShellExecuteEx forwards the string
verbatim, so only macOS is affected.

The trigger was a raw space in the query. Uri.ToString() is a display
form that unescapes %20 back to a literal space (while leaving %2F
alone), so building the launch string that way reintroduced spaces,
most easily via the space-delimited scope parameter. This surfaced
after MSAL began encoding spaces[1] as %20 rather than +; a literal
+ is left untouched by ToString(), which had masked the problem.

Uri.AbsoluteUri keeps the query fully percent-encoded, so %20 stays
%20 and macOS open accepts the URL unchanged.

[1]: AzureAD/microsoft-authentication-library-for-dotnet#5128

Assisted-by: Claude Opus 4.8
Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com>
@mjcheetham mjcheetham force-pushed the sec-release-2.9.0_vnextport branch from e68d8a8 to 329da7f Compare July 14, 2026 17:22
@mjcheetham mjcheetham merged commit 018774a into vnext Jul 15, 2026
27 checks passed
@mjcheetham mjcheetham deleted the sec-release-2.9.0_vnextport branch July 15, 2026 08:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gcm3.0 Targets the next major release of Git Credential Manager - v3.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants