Skip to content

MFA login fails with "CSRF token validation failed" due to duplicate form submission #3370

Description

@yog27ray

New Issue Checklist

Issue Description

Logging in with MFA (OTP) enabled fails with:

CSRF token validation failed. Please refresh the page and try again.

The login returns HTTP 403 with EBADCSRFTOKEN. The password step works; the failure happens on the OTP step. It reproduces on a single dashboard instance, in incognito, with no browser extensions, so it is not the multi-replica / sticky-session scenario from #3015.

Steps to reproduce

  1. Configure a dashboard user with mfa set.
  2. Open the login page, enter username + password, then the one-time password, and submit.
  3. Login fails with "CSRF token validation failed".

Actual Outcome

The OTP step issues two POST /login requests. The first authenticates successfully; Passport's req.logIn then calls req.session.regenerate() (session-fixation protection), which destroys the session that holds the CSRF token (csrf-sync stores the token in req.session). The browser cancels that first response and never receives the regenerated session cookie, so the second request lands on the now-destroyed session, finds no CSRF token, and fails validation with 403.

The duplicate submission originates in LoginForm.react.js: the submit control is type="submit" (which natively submits the form) and its onClick also calls this.formRef.current.submit(), producing a second, redundant submission. On the password step both submissions return 302, so it is harmless; only the MFA step exposes it because the first POST regenerates the session.

Expected Outcome

Login with MFA succeeds; the form is submitted exactly once.

Environment

  • Parse Dashboard version: 9.1.1 (also present on alpha / HEAD)
  • MFA: enabled (OTP)
  • Deployment: single instance (not multi-replica)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions