Problem/Motivation

The authentication code form (provided by src/Controller/TfaLoginController.php) enforces an expiration time of 5 minutes for the "tfa-entry-uid" form uid, which is not configurable (thru the general TFA settings page) nor "pluggable" (by methods/hooks inside a plugin class).

      $metadata = $temp_store->getMetadata('tfa-entry-uid');
      $updated = is_null($metadata) ? 0 : $metadata->getUpdated();
      // Deny access, after 5 minutes since the start of the tfa process.
      if ($updated < (time() - 300)) {
        $temp_store->delete('tfa-entry-uid');
        return $access->andIf(AccessResult::forbidden('Timeout expired.'));
      }

When/if form age exceeds 5 minutes, any further user interaction with the form (sending a code, reloading the page, custom actions implemented by a specific authentication plugin) leads to a generic "Access denied" error which is un-specific and confusing for the user.

To provide some more context: we are developing a Email TFA code plugin, and have decided to allow administrators to decide how long the authentication code should be considered valid (if correct).

Steps to reproduce

  • Setup any TFA method for a user
  • Log out
  • Access the user login form, input correct username/password
  • Wait on the TFA authentication code form for more than 5 minutes
  • try submitting a code
Expected behaviour

I login successfully / I see some contextual error message (depending on the specific authentication plugin)

Actual behaviour

I see a "You are not authorized to access this page." error, with no other options/information.

Proposed resolution

  • Given the "pluggable" nature of this module, it would be useful to implement a "hookable" method (eg, in the "TfaBasePlugin" class) that delegates to the specific plugin to decide when/how/if the "tfa-entry-uid" value expires.
  • Some general configuration option (under "/admin/config/people/tfa") to alter/disable the form uid expiration time (as a failback option if the plugin doesn't set its own) would also be more transparent.
  • A clearer message to the user in case the form has expired
CommentFileSizeAuthor
#3 3390083-3.patch760 bytesnadim hossain

Comments

giuspe created an issue. See original summary.

cmlara’s picture

Version: 2.0.0-alpha2 » 2.x-dev
Related issues: +#2930532: Create the Send Plugin API with a working test

leads to a generic "Access denied" error which is un-specific and confusing for the user.

I will agree that is less than ideal UX.

and have decided to allow administrators to decide how long the authentication code should be considered valid (if correct)

Code validity time is different than a timeout to enter the code, it is possible (depending upon the plugin design) that the code could be used longer than the page timeout when the user logs-in again.

The length of this does need to be balanced, on quick glance this is a timeout for how long we accept a token after the user has entered their password, we don't want this to be an extended period of time as doing so would effectively change this from from a second factor login to a single factor login.

This does sound like it relates to #2930532: Create the Send Plugin API with a working test which perhaps this needs to be considered as part of regarding timing.

It would be interesting if there is any data on how long other services, or implementation allow for a timeout on entering the code.

nadim hossain’s picture

StatusFileSize
new760 bytes

Hi,
I am having this issue in my current project using the TFA Email OTP Plugin and I am using the tfa version 1.7. Till this is fixed and works with 2.x, creating a temporary patch to use it in my project against 1.7 version.
Setting the validation period to 10 minutes to match the highest validation period for a code given by the TFA Email OTP Plugin settings.

toby wild’s picture

Hi,

I've just had this issue come up on a client site. The fact they are allowed to set a 10 minute validation for the TFA token, but the timeout is hardcoded to 5 minutes makes for a very confusing user experience.

The "workaround" is that if they try to use the code after the 5 minutes, and get the Access Denied error, they can re-login and use the code rather than requesting a new one is ok in the short term.

Wouldn't it make more sense that on form submit for the TFA module configuration, if the email validity period is greater than 5 minutes, it automatically updates the timeout to match that selected value, and if it's less than 5 minutes, it defaults to 5 minutes.

cmlara’s picture

The fact they are allowed to set a 10 minute validation for the TFA token, but the timeout is hardcoded to 5 minutes makes for a very confusing user experience.

One could also contend that this is the fault of the email token for allowing a 10 minute timeout without informing the site owner. That said I can understand why they would want to, you need to allow enough time for a user to pull their email client and submit the code. We (TFA) however need to defend against the browser being left unattended or tokens being shared.

We allow a long timeout for the TOTP token, however that is probably more historical. I was working with a TOTP solution the other day that only allowed 1 sync difference. In the past we needed to worry about very low precision crystal oscillators that could drift by over 10 minutes a year (with the battery lasting 3+ years). Now we use most often use devices with built in clock synchronization and server infrastructure with sub second time holding accuracy. There could be a good argument that in a future version we should hard code a shorter limit in the TOTP plugin.

Wouldn't it make more sense that on form submit for the TFA module configuration, if the email validity period is greater than 5 minutes, it automatically updates the timeout to match that selected value, and if it's less than 5 minutes, it defaults to 5 minutes.

From a security standpoint, not necessarily. As noted in #2 there is a difference between 'the token is valid' and 'we are validating a 2nd factor login'. The first part is the on the token plugin, the second is TFA's responsibility, we can't legitimately deffer that to a 3rd party, we need to have some level of it from our side. A configurable window is an option inside the TFA settings, however it would certainly need boundaries (and I would prefer we have some sort of data reference to look at.