commit 3f6809bcdf88268543c0ee75ae6c3a3fbcf23df8
parent 9ff577a7b4d86384ec9d35ae13dfab3a5be1553b
Author: BlackDex <black.dex@gmail.com>
Date: Thu, 7 Nov 2019 17:11:29 +0100
Fixed issue/request #705
Added a config option to disable time drifted totp codes.
Default is false, since this is what the RFC recommends.
Diffstat:
3 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/.env.template b/.env.template
@@ -140,6 +140,18 @@
## After that, you should be able to follow the rest of the guide linked above,
## ignoring the fields that ask for the values that you already configured beforehand.
+## Authenticator Settings
+## Disable authenticator time drifted codes to be valid.
+## TOTP codes of the previous and next 30 seconds will be invalid
+##
+## According to the RFC6238 (https://tools.ietf.org/html/rfc6238),
+## we allow by default the TOTP code which was valid one step back and one in the future.
+## This can however allow attackers to be a bit more lucky with there attempts because there are 3 valid codes.
+## You can disable this, so that only the current TOTP Code is allowed.
+## Keep in mind that when a sever drifts out of time, valid codes could be marked as invalid.
+## In any case, if a code has been used it can not be used again, also codes which predates it will be invalid.
+# AUTHENTICATOR_DISABLE_TIME_DRIFT = false
+
## Rocket specific settings, check Rocket documentation to learn more
# ROCKET_ENV=staging
# ROCKET_ADDRESS=0.0.0.0 # Enable this to test mobile app
diff --git a/src/api/core/two_factor/authenticator.rs b/src/api/core/two_factor/authenticator.rs
@@ -11,6 +11,8 @@ use crate::db::{
DbConn,
};
+pub use crate::config::CONFIG;
+
pub fn routes() -> Vec<Route> {
routes![
generate_authenticator,
@@ -118,9 +120,11 @@ pub fn validate_totp_code(user_uuid: &str, totp_code: u64, secret: &str, conn: &
.expect("Earlier than 1970-01-01 00:00:00 UTC").as_secs();
// The amount of steps back and forward in time
- let steps = 1;
- for step in -steps..=steps {
+ // Also check if we need to disable time drifted TOTP codes.
+ // If that is the case, we set the steps to 0 so only the current TOTP is valid.
+ let steps = if CONFIG.authenticator_disable_time_drift() { 0 } else { 1 };
+ for step in -steps..=steps {
let time_step = (current_time / 30) as i32 + step;
// We need to calculate the time offsite and cast it as an i128.
// Else we can't do math with it on a default u64 variable.
diff --git a/src/config.rs b/src/config.rs
@@ -275,6 +275,10 @@ make_config! {
/// Note that the checkbox would still be present, but ignored.
disable_2fa_remember: bool, true, def, false;
+ /// Disable authenticator time drifted codes to be valid |> Enabling this only allows the current TOTP code to be valid
+ /// TOTP codes of the previous and next 30 seconds will be invalid.
+ authenticator_disable_time_drift: bool, true, def, false;
+
/// Require new device emails |> When a user logs in an email is required to be sent.
/// If sending the email fails the login attempt will fail.
require_device_email: bool, true, def, false;