Summary
The integration setup wizard navigates to the redirect_uri query parameter verbatim on Continue and Cancel, with no scheme, host or registered-URI check. A crafted link can send a signed-in user to any external site (open redirect), and a javascript: value runs script in the platform's origin.
Affected code
autogpt_platform/frontend/src/app/(platform)/auth/integrations/setup-wizard/page.tsx:99 (redirectURI = searchParams.get("redirect_uri"))
.../setup-wizard/page.tsx:151 (handleComplete: window.location.href = `${redirectURI}?${params.toString()}` ) and :167 (handleCancel, same pattern)
- The page already fetches the OAuth app (
useGetOauthGetOauthAppInfo(clientID), line 102) but only for display; nothing compares redirect_uri to the app's registered URIs. client_id is also optional.
This is the same class as #15047/#15048 (and PR #15057), but those and the PR only cover /auth/authorize (authorize/page.tsx); the setup wizard is a separate page and is not touched by that PR.
Trigger / steps to reproduce
- While signed in (the page is behind the protected
/auth/integrations prefix), open /auth/integrations/setup-wizard?providers=<base64 of [{"provider":"github"}]>&redirect_uri=https://evil.example/phish&state=x.
- Click "Cancel" (always enabled; "Continue" works once providers are connected).
- The browser navigates to
https://evil.example/phish?error=user_cancelled&error_description=...&state=x.
For script execution use redirect_uri=javascript:<code>//; the code builds javascript:<code>//?error=user_cancelled&... and the trailing query becomes a JS comment.
Expected vs actual
Expected: only the client's registered redirect URIs (or at least same-origin / http(s) URLs) are navigated to; anything else shows an error.
Actual: any string is assigned to window.location.href.
Severity
Medium. A trusted-domain page that can be turned into a phishing redirect with one click and, through javascript:, into script execution with the victim's session. It needs the victim to open a crafted link and click a button.
How confirmed
Read the page. Reproduced the exact navigation pattern in a local browser page (http://localhost): a button doing window.location.href = `${redirectURI}?${params.toString()}` with redirect_uri=javascript:document.title='js-ran:'+location.origin// executed the script in the page origin (the page text became js-ran:http://localhost:8765). I did not run the full platform stack, so the setup-wizard page itself was not exercised end to end.
Fix feasibility
Yes: validate redirectURI with the same safety helper being added for the authorize page (redirect-safety.ts in PR #15057) and check it against the app's registered URIs before navigating.
Summary
The integration setup wizard navigates to the
redirect_uriquery parameter verbatim on Continue and Cancel, with no scheme, host or registered-URI check. A crafted link can send a signed-in user to any external site (open redirect), and ajavascript:value runs script in the platform's origin.Affected code
autogpt_platform/frontend/src/app/(platform)/auth/integrations/setup-wizard/page.tsx:99(redirectURI = searchParams.get("redirect_uri")).../setup-wizard/page.tsx:151(handleComplete:window.location.href = `${redirectURI}?${params.toString()}`) and:167(handleCancel, same pattern)useGetOauthGetOauthAppInfo(clientID), line 102) but only for display; nothing comparesredirect_urito the app's registered URIs.client_idis also optional.This is the same class as #15047/#15048 (and PR #15057), but those and the PR only cover
/auth/authorize(authorize/page.tsx); the setup wizard is a separate page and is not touched by that PR.Trigger / steps to reproduce
/auth/integrationsprefix), open/auth/integrations/setup-wizard?providers=<base64 of [{"provider":"github"}]>&redirect_uri=https://evil.example/phish&state=x.https://evil.example/phish?error=user_cancelled&error_description=...&state=x.For script execution use
redirect_uri=javascript:<code>//; the code buildsjavascript:<code>//?error=user_cancelled&...and the trailing query becomes a JS comment.Expected vs actual
Expected: only the client's registered redirect URIs (or at least same-origin / http(s) URLs) are navigated to; anything else shows an error.
Actual: any string is assigned to
window.location.href.Severity
Medium. A trusted-domain page that can be turned into a phishing redirect with one click and, through
javascript:, into script execution with the victim's session. It needs the victim to open a crafted link and click a button.How confirmed
Read the page. Reproduced the exact navigation pattern in a local browser page (
http://localhost): a button doingwindow.location.href = `${redirectURI}?${params.toString()}`withredirect_uri=javascript:document.title='js-ran:'+location.origin//executed the script in the page origin (the page text becamejs-ran:http://localhost:8765). I did not run the full platform stack, so the setup-wizard page itself was not exercised end to end.Fix feasibility
Yes: validate
redirectURIwith the same safety helper being added for the authorize page (redirect-safety.tsin PR #15057) and check it against the app's registered URIs before navigating.