Skip to content

Current 2FA solution can lock users out of their accounts #201

Closed
@LeoniePhiline

Description

@LeoniePhiline
  • Version: v1.7.4
  • Laravel Version: v8.22.1
  • PHP Version: v7.4.13

Description:

The current two factor authentication solution sets 2fa to enabled without requiring a confirmation (via TOTP) that the authenticator app is actually set up.

Steps To Reproduce:

The current solution works like this:

  1. POST /user/two-factor-authentication, the user's two_factor_secret is stored. (2fa is now enabled!)
  2. GET /user/two-factor-qr-code, show QR code and ask user to scan the code with their app.
  3. GET /user/two-factor-recovery-codes, show recovery codes and ask the user to save them.
  4. User abandons the process before setting up their authenticator app or saving the recovery codes and is now locked out of their account.

They could abandon the process because they first need to choose one of the many TOTP generators in the app store, and get side tracked, or their session times out, or they click the back button, or close their tab, or their computer crashes, ... Definitely 2fa must not be enabled before it is confirmed by a generated OTP.

How To Fix It:

  1. GET /user/two-factor-qr-code generates a QR code from a new two factor secret that is stored in the session.
  2. GET /user/two-factor-recovery-codes, show the recovery codes to the user, ask them to save them.
  3. The user is asked to set up their authenticator app with this QR code and enter a resulting TOTP code. This confirms that they have set up their authenticator (else they cannot generate a valid code), and can also (by written explanation) be used as confirmation that recovery codes were stored in a safe place.
  4. POST /user/two-factor-authentication, receives a new parameter: code. The code is validated using the two factor secret stored in the session.
  5. If the code is valid, the two factor secret from the session is written into the user table (= enabling 2fa, now for real). If not, then the response indicates that the user did not enter a valid code and must re-try.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions