Browse Source

Strip Spaces from TOTP Code

Some users enter the TOTP code with a space, which breaks authentication. This strips the space from
the user-entered TOTP code and validates against it.
master
Alaina Hardie 6 years ago
parent
commit
8887babd76
  1. 6
      lib/two_factor_authentication/models/two_factor_authenticatable.rb
  2. 5
      spec/lib/two_factor_authentication/models/two_factor_authenticatable_spec.rb

6
lib/two_factor_authentication/models/two_factor_authenticatable.rb

@ -39,7 +39,7 @@ module Devise
drift = options[:drift] || self.class.allowed_otp_drift_seconds drift = options[:drift] || self.class.allowed_otp_drift_seconds
raise "authenticate_totp called with no otp_secret_key set" if totp_secret.nil? raise "authenticate_totp called with no otp_secret_key set" if totp_secret.nil?
totp = ROTP::TOTP.new(totp_secret, digits: digits) totp = ROTP::TOTP.new(totp_secret, digits: digits)
new_timestamp = totp.verify_with_drift_and_prior(code, drift, totp_timestamp) new_timestamp = totp.verify_with_drift_and_prior(without_spaces(code), drift, totp_timestamp)
return false unless new_timestamp return false unless new_timestamp
self.totp_timestamp = new_timestamp self.totp_timestamp = new_timestamp
true true
@ -103,6 +103,10 @@ module Devise
private private
def without_spaces(code)
code.gsub(/\s/, '')
end
def random_base10(digits) def random_base10(digits)
SecureRandom.random_number(10**digits).to_s.rjust(digits, '0') SecureRandom.random_number(10**digits).to_s.rjust(digits, '0')
end end

5
spec/lib/two_factor_authentication/models/two_factor_authenticatable_spec.rb

@ -86,6 +86,11 @@ describe Devise::Models::TwoFactorAuthenticatable do
expect(do_invoke(code, instance)).to eq(true) expect(do_invoke(code, instance)).to eq(true)
end end
it 'authenticates a code entered with a space' do
code = @totp_helper.totp_code.insert(3, ' ')
expect(do_invoke(code, instance)).to eq(true)
end
it 'does not authenticate an old code' do it 'does not authenticate an old code' do
code = @totp_helper.totp_code(1.minutes.ago.to_i) code = @totp_helper.totp_code(1.minutes.ago.to_i)
expect(do_invoke(code, instance)).to eq(false) expect(do_invoke(code, instance)).to eq(false)

Loading…
Cancel
Save