OAuth2 - No way to force re-authentication

stromb0li

Well-known member
Licensed customer
Affected version
2.3.11
This is gray on a feature ask vs bug, but hoping I can sneak it into the bug fix bucket as a potential security improvement.

Ask: Support prompt=login (and ideally max_age=0) at the OAuth2 authorization endpoint (e.g. /oauth2/authorize endpoint) so relying parties can force re-authentication

TLDR: Apps that use XenForo as an OAuth2 provider currently have no way to force a fresh login. If a user "logs out" of the app and tries to sign back in, they get silently logged straight back into the same account. There's no supported way to say "make this person authenticate again", which means "log out and sign in as someone else" is effectively impossible from the OAuth2 client. This is arguably a security gap as without server-side re-auth, "log out" doesn't actually hold and presents risk on shared devices / kiosk scenarios. E.g. the next person can silently resume the previous user's session through any connected app, even though they hit logout in the app.

Scenario:
I'm using the standard authorization code + PKCE flow. If I follow the best practice for native apps (RFC 8252), the app runs the authorization request in an in-app browser tab, which by design shares cookie/session state with the system browser (RFC 8252 §3 defines the in-app browser tab as retaining the browser's full authentication state).

When the user signs out of my app, the app throws away its tokens, but the browser still holds a valid XenForo session cookie. So the next time they hit "sign in," they're not prompted for anything, they're "magically" auto-logged back into the same account. From the user's point of view, logout didn't really do anything, and there's no way to switch accounts.

This is working as designed for SSO, and normally that's what you want. The problem is there's no way to opt out of it when you need to.

Ask:
Accept prompt=login on the /oauth2/authorize endpoint in XenForo. When the parameter is passed, actively re-authenticate the user before continuing the flow (show the login form and require credentials even if a valid session cookie exists; then resume the authorization normally). Given the goal is account-switching, the re-auth prompt should let the user enter different credentials, not just silently reconfirm the current session.

For any prompt value you don't implement, I'd suggest ignoring it rather than erroring, which keeps things consistent with RFC 6749 §3.1 (servers must ignore unrecognized request parameters) and avoids breaking clients that send other values.

To be clear, this isn't a request to implement OpenID Connect. prompt and max_age originate in OIDC, but I'm only asking for this one parameter to be honored on the existing OAuth2 endpoint. RFC 6749 §8.2 explicitly covers defining new endpoint parameters, and §3.1 already requires unrecognized ones to be ignored, so adding this can't break existing integrations. It's also a de facto standard at this point; Google, Okta, Auth0, Keycloak, and Entra ID all honor prompt=login.

max_age as a secondary ask. max_age (force re-auth if the last login is older than N seconds) would be great too, but I get that's a much bigger ask given you've have to track the user's last-authentication timestamp, and in OIDC proper that surfaces as an auth_time claim in the ID token.

Why I can't just fix this on my end
By RFC 8252's design, the app can't touch the browser's cookie jar, so there's no clean client-side way to clear the session. The only workaround is to run the flow in an ephemeral/incognito browser session (prefersEphemeralWebBrowserSession on iOS, an incognito Custom Tab on Android). However, this breaks SSO for the normal sign-in case, behaves inconsistently across platforms, and forces me into per-platform hacks to fake a consistent login experience. The other "fix" is telling users to open the forum in their actual browser and sign out manually, which is super confusing to the end user.

References
 
Back
Top Bottom