Skip to content

[Bug]: OAuth grant page (LoginFlowGrant.vue) broken in Chrome (works in Firefox) — double form submission invalidates state token, regression of #33164 #62327

Description

@janLo

⚠️ This issue respects the following points: ⚠️

  • This is a bug, not a question or a configuration/webserver/proxy issue.
  • This issue is not already reported on Github OR Nextcloud Community Forum (searched, no matches for this regression against the current Vue-based grant page).
  • Nextcloud Server is up to date (tested on 34, a currently supported version).
  • I agree to follow Nextcloud's Code of Conduct.

Bug description

Broken in Chrome. Works correctly in Firefox. (These are the two browsers we tested ourselves. The original #33164 additionally reported Chromium, Edge, and Safari as affected — we haven't independently verified those, flagging that distinction since some use a different engine than Chrome.)

When approving an OAuth2 client via the login flow's grant page, the "Grant access" submit button has no disabled/loading state while the form is submitting. In Chrome this allows the form to submit twice from a single page load — confirmed via server logs: the grant page loads exactly once, then two POST /login/flow requests fire two seconds apart with no page reload in between. The first submission succeeds server-side; the second, reusing the same now-invalidated stateToken, fails with 403 "Access forbidden. State tokens do not match." In Firefox, the same steps complete successfully every time.

This looks like a regression of #33164, fixed in 2022 by disabling the button in core/js/login/grant.js. That file no longer exists — the grant page was rewritten as core/src/views/LoginFlowGrant.vue, and the current version (confirmed by reading the source on master as of this writing) has no equivalent protection: no :disabled binding on the <NcButton type="submit">, and the onSubmit handler only intercepts the event when password re-confirmation is required.

Steps to reproduce

  1. In Chrome (fails; the same steps in Firefox succeed — other browsers untested by us), register an OAuth 2.0 client (Admin settings → Security → OAuth 2.0 clients).
  2. Start an authorization_code flow against /apps/oauth2/authorize from that client.
  3. Log in, reach the "Grant access" screen.
  4. Click "Grant access" once.
  5. Observe two POST /login/flow requests in the server log (or browser devtools network tab) from that single click/page load — the second fails with 403 "state tokens do not match," even though only one page load and one intentional click occurred.

Expected behavior

The submit button (or the form) should be protected against re-submission immediately on click, equivalent to what #33166 added to the pre-rewrite page — and should work as reliably in Chrome as it currently does in Firefox.

Nextcloud Server version

34

Additional info

Verified via correlated log inspection (OAuth client application, reverse proxy, and Nextcloud's own nextcloud.log) that Nextcloud's server-side OAuth2/state-token handling is correct on every attempt — the first submission always completes successfully. Confirmed the browser does not reload/navigate between the two submissions (single GET /login/flow/grant followed by two POST /login/flow, no intervening page load). We tested Chrome (reproduces) and Firefox (does not reproduce) ourselves; the original #33164 also lists Chromium, Edge, and Safari as affected, which we have not independently confirmed.

Current file: https://github.com/nextcloud/server/blob/master/core/src/views/LoginFlowGrant.vue

This is pure client-side JS behavior, independent of OS/PHP/webserver/database, so those fields are omitted.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    Status
    To triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions