8000 Avoid URLSearchParams.size when parsing the callback URL by choksi2212 · Pull Request #355 · keycloak/keycloak-js · GitHub
[go: up one dir, main page]

Skip to content

Avoid URLSearchParams.size when parsing the callback URL - #355

Closed
choksi2212 wants to merge 1 commit into
keycloak:mainfrom
choksi2212:fix/callback-url-searchparams-size-53895
Closed

choksi2212 wants to merge 1 commit into
keycloak:mainfrom
choksi2212:fix/callback-url-searchparams-size-53895

Conversation

@choksi2212
Copy link
Copy Markdown

Fixes #359

What

One-line change in #parseCallbackUrl: check the query string directly instead of url.searchParams.size > 0, mirroring the fragment branch right below it.

Root cause

URLSearchParams.size shipped in Safari 17 (Sept 2023), Chrome 113 and Firefox 112. On Safari 16 — which is what iPhone 8/X and other iOS 16-capped devices run — url.searchParams.size is undefined, so undefined > 0 is false and the whole query branch is skipped. The callback is never parsed, the stored kc-callback-{state} entry is never consumed, and with onLoad: 'login-required' the adapter bounces back to the auth server with a stale redirect_uri that carries the old ?code=...&state=..., which the server rejects (LOGIN_ERROR invalid_redirect_uri) — the infinite loop from the issue.

The property was introduced by the URL parsing refactor in 82924d0 (#143); before that, the same check was done on the raw string and worked everywhere.

Verification

  • Loaded the real module in Node with the private method made callable and URLSearchParams.prototype.size deleted to simulate Safari 16:
    • On pristine main: the standard ?code=...&state=... callback returns undefined — the exact miss from the issue.
    • With this change: the same callback parses (code, state, session_state, iss, and the stripped newUrl), and results are identical with and without size present, so nothing changes for modern browsers. Error callbacks (error=...&state=...) parse too, unsupported params survive in newUrl while OAuth params are stripped, fragment mode is unaffected, and the degenerate ?-only URL still counts as no callback, matching the old .size > 0 behavior.
  • Added a Playwright regression test (login-without-searchparams-size.spec.ts) that deletes the property in the page via addInitScript, logs in with responseMode: 'query', and expects the callback to be parsed and the user authenticated. On pristine main this test cannot pass because the callback is lost; it runs in the CI integration job.
  • npm run lint (ts-standard) passes; tsc --noEmit reports no new errors for the touched region or the new spec.

URLSearchParams.size shipped in Safari 17 (Sept 2023); on Safari 16 and
other browsers without it, url.searchParams.size is undefined, so the
condition was false and the query callback was skipped entirely. Apps
that require a login then bounced between the application and the auth
server, with the auth server rejecting the stale redirect URI, looping
until the browser gives up (keycloak/keycloak#53895).

Check the query string directly instead, mirroring the fragment branch
directly below, which restores the behavior the URL parsing had before
82924d0 introduced the property. Also covers the degenerate '?'-only
case the same way the old check did: the params parse to nothing, so
the callback is still treated as absent.

Signed-off-by: choksi2212 <choksi2212@users.noreply.github.com>
@choksi2212
choksi2212 requested a review from jonkoops as a code owner October 13, 2026 17:48
@choksi2212
Copy link
Copy Markdown
Author

First PR from this fork, so the CI workflows are waiting on maintainer approval before they can run. Everything's verified locally — happy to wait, just flagging it in case it slipped by.

@jonkoops
Copy link
Copy Markdown
Contributor

Thanks for the fix, but we target baseline widely available as a minimum platform target. Since URLSearchParams.size meets that requirement, it is within our evergreen support target.

Closing this PR.

@choksi2212
Copy link
Copy Markdown
Author

Understood — thanks for the context. Baseline "widely available" as the platform bar noted for future contributions; under that target URLSearchParams.size is fine and this fix is unnecessary. Closing makes sense.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Account Console infinite auth loop on iOS 16 / Safari 16 due to URLSearchParams.size (keycloak-js 26.x)

2 participants

0