Facilitate 2FA+MultiFactor compatibility (2FA/two-factor -> MFA/multi-factor)

Created on 12 August 2017, over 7 years ago
Updated 15 April 2024, 9 months ago

From the CMX.zone distributions project, filing as a feature request for feedback both from BackdropCMS core and Drupal 7.x core.

External references:

- BackdropCMS: "Facilitate 2FA+MultiFactor compatibility (2FA/two-factor -> MFA/multi-factor)" https://github.com/backdrop/backdrop-issues/issues/2788

As initially posted at CMX.zone + BackdropCMS.org:

(version numbering issues related to Backdrop is irrelevant, but posting "as-is" here)

Two concerns, but only 1 relevant for core, hopefully with at least a clarification / guideline in place before or on the release of 1.8. Not sure how much needs to be done code-wise for core. If a separate/new API is the answer, then the initial question is if we can do something "imperfect" only partially to help various ports of contrib modules from D7 head "in the right direction" or take a "unified approach".

Most (all?) of the existing/relevant modules may well reside in contrib, but the question is **how core can help them avoid race conditions and incompatibilities**. Does that constitute an effort too big to consider for inclusion in 1.8.x?

For actual examples, here is my initial list of the most relevant contrib modules:

- https://www.drupal.org/project/tfa
- https://www.drupal.org/project/tfa_basic (TOTP++)
- https://www.drupal.org/project/u2f
- https://www.drupal.org/project/yubikey (the latest Yubikey's also have u2f, but the current YK module does not have that capability)
- https://www.drupal.org/project/login_one_time (authorised roles/admins may send such links from inside the site to users that has problems logging in. The destination path provided in the setup of that module should not come in conflict with other 2FA/MFA requirements for that user/login.)
- https://www.drupal.org/project/login_destination (similar problem as with login_one_time: also should not come in conflict with 2FA/MFA, but be handled at the end of the login process (race condition))
- https://www.drupal.org/project/passwordless (enforces logins using an email link instead of the normal password, but the second (or third++, as in MultiFactor) factor(s) should still apply AFTER that)
- https://www.drupal.org/project/legal ("Terms-of-Service" module that needs reconfirmation/acceptance of new revisions upon login before granting access (if not accepting, may remove related roles, but still allow login (with less features). That process should not prevent 2FA/MFA to kick in when applicable.)
- https://www.drupal.org/project/apply_for_role (buy membership level (roles for Premium.content++))

+ Other modules related to **Registration** (several candidates).

Examples:

Below are some examples on which "issues" we need to fix when porting those modules to BackdropCMS, related to the above modules (based on current situation/experience from D7):

(Notice that these examples are mostly issues that needs to be fixed in each contrib module. THIS feature request related to BD core is simply a question of identifying what/how core can facilitate and help guide these ports into a constructive direction where race conditions and incompatibilities can be avoided from the start.)

- passwordless (email link instead of password) is most often/likely the first part of the login process. It does not redirect properly when (some) other(s) of these modules are active, so that TFA/Yubikey/etc. does not get to work after this module has accepted the login. The result is currently aborted logins.

- TFA_basic (TOTP/Google Authenticator compatible) should allow the login to proceed through other steps as well, such as subsequent Yubikey / U2F.

- ToS updates may aim to PREVENT login if the new ToS revision is not accepted, thus it needs to come FIRST in the login process (second if using "passwordless" / email login links), before the TOTP/Yubikey/U2F kicks in.

- Yubikey module has options for disabling username/password and only use YK for login. When an account also has activated TOTP or email-login (passwordless), those should also get to work without conflicts with YK. This part of the features might be the one we want in core: the very setting per account for how many and which authentication elements are required (also depending on roles; so the combination of roles is key here)

- legal does not get to do its renewal of acceptance on **new ToS revisions** if some of the above modules also kick in at the same login time.

(PS. The world is about to realize that **two-factor is important but not enough** by itself, depending on the sensitivity of the content/accounts/site(s) in question. We need to cater for all. If you look at for example Google's password recovery process, that is already multi-factor (and a great example). **We need to aim for multi-factor functionality** already now, not just two-factor.)

Further specifications and examplification / insights into the relevant login process(es)

The race (conditions) - "the order of things":

2 alternative starting points

A. User arrives "at the login logic" through a (valid) one-time login link (either through "forgotten password link or by another user/admin sending out a "one-time login link" via something like the "one-time-login module.)

B. Normal login starting at the login page asking for credentials.

If A., then skip Stage 1 and go straight to Stage 2 below:

If B., then start with Stage 1:

Stage 1 - which credentials are initially required (or "enough")?

- Provide either user name, email or (if assigned to the actual account, otherwise not) Yubikey OTP.
- IF the passwordless module is activated, it should accept ANY of the above 3, and then send the login link by email.
- (If the site is NOT enforcing the email link "route", then any one of those 3 will identify the account.)
- IF static password is required for login, then the password field should also be required on the initial login page.

IF either the password is not required (either from settings, or in the case of using a One-Time login link), OR the correct password was given, then check for extra requirements (factors):

Stage 2 - Second- or Multi-Factor logic

- IF the identified account has one or more registered Yubikey(s), ask for any one of them ONLY if any of them was not used instead of the username in step 1...
- After username/(password)/Yubikey = verified, check if that account is member of any role that is set to REQUIRE TOTP. If so, show the TFA authentication field.
- If TOTP/TFA is provided correctly, or if it is not needed, check if U2F is required (Multi-Factor is possible, may require 2-3++ FACTORS depending on the site in question). If it is, and if a correct token is provided, then proceed to the next check:
- If the actual user is either not member of any roles that requires extra factors, or does not have a registered Yubikey (IF the Yubikey module is set to allow bypassing it for accounts that does not have any registered Yubikey yet...), then proceed:

After the "2FA"/"MFA" alternatives have been passed, skip to Stage 3...

Stage 3 - Legal module active? (Terms-of-Service (re-)confirmation)

Check if the Legal module (is active and...) requires (first or new) confirmation for the current or new ToS revision.

- If it is not active, or not requiring a confirmation at this point, skip to Stage 4.
- If it does require (new) confirmation, let Legal present itself and then pass the user on to Stage 4 only if the user accepts the ToS.

Stage 4 - Figure out the "landing page" after the authentication is ok

Landing page scenarios:

1. User arrived through a one-time login link WITH a destination parameter, then go to that page. (In case that was a "forgotten password" link, then the destination page is the User edit page WITHOUT requiring the current password. In case it was just a normal One-time-login link with the user edit page as the destination parameter, then set that user edit page so that it DOES require the current password in order to change either password or email (default setting).)

2. A destination parameter exists in the current URL: go there. (may be because the user arrived through a one-time login link WITH such a parameter, or because the user was forced to log in to access a specific page, which also means there is a destination in the URL)

3. User arrived through a one-time login link WITHOUT a destination parameter, then check if there are any default landing pages for this user, either given by context (through Login_destination module or PageManager or the like), or by user role related rules. If several exists, provide them as options/suggestions in a bullet list of links.

Core features: The flexibility for Stage 1

I think (hope...) that the only relevant part for Drupal/Backdrop core in this context is all in Stage 1: Depending on which (contrib.) modules are activated on the actual site, the site figures out during Stage 1 the appropriate route and next steps. All the logic of Stage 2 should reside within whichever extra/contrib. modules are activated on the site, hence not an issue for core. (EXCEPT perhaps if we agree to put both the TFA and TFA_Basic modules in core (might make sense), then TOTP etc. are handled in/by core.)

The core MFA functionality should have settings for the following:

- how many factors are required in total
- which factors are required (cannot be swapped out for others) / which of the factors are optional, and **which can be "mixed-and-matched".**
- specifying different amount of factors and different optional factors PER ROLE, with optional setting so that if not needed, one rule is enough.
- re-orderable (drag-n-drop) weighted list of roles to set the priority for users that are members of more than one role

The core functionality should be indifferent as to which extra/contrib. modules are (or will be) used on the site. It should be made so that it is totally up to each extra module to integrate correctly and find its way into the (appropriate place in the) "race".

Examples related to core configuration (Stage 1 above):

- If requiring 4 factors, that may be any mix of a) user name or email, b) static password, c) Any of several registered TOTP entries (more than 1 per account is very nice for extra flexibility), d) U2F, e) Any of several registered Yubikey OTP's. - or f) .
- If requiring ("only") 3 factors, that may be any one of the above, but for example then maybe the email address will either be required on the first page OR if giving the user name instead; a link will be sent to the email ONLY if any corresponding Yubikey OTP OR TOTP is provided... If not provided, no email link is sent, and login is prevented.
- The system admin should be able to select whether the password field may be ommitted in case at least 2 of the following are given: Yubikey OTP / U2F / TOTP. (assuming here that 1 of them is required anyway, with or without the password.) Alternatively, if only one of those 3 are provided, then the system will insist on sending a login link to any one of the email addresses belonging to that account. It will first send to the primary email, and on the confirmation page after the email has been sent, it should ask the user if he/she wants to use any of the other emails instead. If so, then that email must be specified on a new field that appears if clicking on this link, and then the process goes on as usual.

Compatibility with Maintenance mode...(!)

For users that are member of any 1 role that is allowed to use the site in maintenance mode (separate, independent/existing core permission), all elements of this login logic should work also when the site is in maintenance mode...

(Please keep in mind that "Maintenance mode" is not just a mode we use temporarily/sometimes/short-time; It has several good use cases and there are many sites where teams are working fully in maintenance mode for months, even "permanently" until a whole other version of the site is released, so this concern is quite valid.)

D.o references:

- TFA: #2241821: Plan for TFA 7.x-2.2 release
- TFA: #2381729: Drupal 9 port and time to consider interoperability with TFA modules
- TFA: 🐛 Maintenance mode blocks TOTP TFA entry Fixed
- TFA: #2537652: Allow multiple TFA registrations per account
- TFA: #2483597: How do I set up more than one application?
- TFA: #2507409: Immediately logged out when using password reset form
- Yubikey: #2745583: U2F and TFA support (flexibility, extra security + multi-factor)
- Yubikey: #2343845: More flexible Yubikey login scheme allow login mode per role
- Legal: #2085227: One-time login links fails when ToS needs to be (re-)verified

Aaaaand..: Masquerading compatibility (Just-for-the-record, potentially not relevant for core)

The Masquerade module (and ditto Devel function) needs customizeable (preferably both roles-based and optionally user-id based) settings to..: a) decide who should be allowed to masquerade into such accounts while bypassing all the above..., and b) whenever any one of these options should be enforced also while masquerading, it should also work in that context (so it does not prevent masquerading, yet still enforce the desired security). (Some admins may need to be blocked from certain accounts within the roles they are generally allowed to masquerade to (...), for example by enforcing the target user's physical Yubikey also for masquerading...)

Feature request
Status

Active

Version

11.0 🔥

Component
User system 

Last updated about 13 hours ago

Created by

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

Production build 0.71.5 2024