Skip to content

Frontend: integration setup wizard navigates to an unvalidated redirect_uri (open redirect and javascript: execution) #15303

Description

@capy-ai

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

  1. 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.
  2. Click "Cancel" (always enabled; "Continue" works once providers are connected).
  3. 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.

Activity

  1. ntindle commented on Oct 8, 2026

    @ntindle
    Member

    Backfill validation: reproduced

    Image: significantgravitas/autogpt:latest @ sha256:122929723f57b8927af016d606ae21b21c03a012c2de1d9c30b1c8359e9157f1 (Hub v0.8.3 / sha-73cae306b4f6b197d2e1eaaa3162c326ec0ab076 / oci_revision 73cae306b4f6b197d2e1eaaa3162c326ec0ab076), pulled 2026-10-08 13:08 CT (ok_up_to_date), run sweep-20261008T1808.

    Verdict: reproduced (built frontend bundle in the image)

    What we checked

    The built auth/integrations/setup-wizard page reads redirect_uri from the query and does window.location.href = `${redirect_uri}?${params}` on cancel/complete. There is no scheme, host or registered-URI check.

    Limits

    Did not navigate it in a signed-in browser.

    Suggestion

    Validate redirect_uri against the OAuth app's registered URIs (and require http(s)) before navigating.

    Host evidence: /workspace/autogpt-backfill/evidence/15303/sweep-20261008T1808/ (host-local)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions