fix(oauth2): prevent false callback matches on root path URLs (#7315)

* fix(oauth2): prevent false callback matches on root path URLs and handle errors first

Move error check before callback URL matching in onWindowRedirect so
OAuth error responses are rejected immediately. Remove redundant error
param check from matchesCallbackUrl and require a code param or hash
fragment to match, preventing false positives on intermediate pages
when the callback URL is a root path like https://hostname/.

* fix(oauth2): clarify error handling comment

Remove "on the callback URL" from comment since error checking
now happens before callback URL matching.
This commit is contained in:
lohit
2026-02-27 15:18:51 +00:00
committed by GitHub
parent a9709fb82a
commit 4f4faec359
2 changed files with 57 additions and 9 deletions

View File

@@ -2,7 +2,13 @@ const { BrowserWindow } = require('electron');
const { preferencesUtil } = require('../../store/preferences');
const matchesCallbackUrl = (url, callbackUrl) => {
return url ? url.href.startsWith(callbackUrl.href) : false;
if (!url) return false;
// Match the callback URL and require an OAuth2 response indicator
// (code query params for authorization code flow, or hash fragment for implicit flow).
// This prevents false matches on intermediate pages (e.g. /auth/login) when the
// callback URL is a root path like https://hostname/.
return url.href.startsWith(callbackUrl.href)
&& (url.searchParams.has('code') || url.hash.length > 1);
};
const authorizeUserInWindow = ({ authorizeUrl, callbackUrl, session, additionalHeaders = {}, grantType = 'authorization_code' }) => {
@@ -145,14 +151,8 @@ const authorizeUserInWindow = ({ authorizeUrl, callbackUrl, session, additionalH
callbackUrlObj = null;
}
// Check if redirect is to the callback URL and contains an authorization code
if (callbackUrlObj && matchesCallbackUrl(urlObj, callbackUrlObj)) {
finalUrl = url;
window.close();
return;
}
// Handle OAuth error responses
// Handle OAuth error responses first, so we reject with
// a descriptive error instead of resolving with a null authorization code
if (urlObj.searchParams.has('error')) {
const error = urlObj.searchParams.get('error');
const errorDescription = urlObj.searchParams.get('error_description');
@@ -165,6 +165,13 @@ const authorizeUserInWindow = ({ authorizeUrl, callbackUrl, session, additionalH
};
reject(new Error(JSON.stringify(errorData)));
window.close();
return;
}
if (callbackUrlObj && matchesCallbackUrl(urlObj, callbackUrlObj)) {
finalUrl = url;
window.close();
return;
}
}