sign in issue with module Encryptor and wrong value returned by ::BCrypt::Engine.hash_secret() after session expiration
Environment
- Ruby 2.7.2p137
- Rails 6.1.3.2
- Devise 4.8.0
devise :database_authenticatable, :registerable, :confirmable, :lockable,
:timeoutable, :trackable, :recoverable, :rememberable, :validatable,
password_length: 6..64
Current behavior
I have an application where sessions expire in 12 hours, config.timeout_in is also set to 12.hours. After session expires and if a browser (I am using Brave, which is a fork from Chrome) is still open, a user won't be able to sign in with authentication error from devise. I ran a debug session and found out that the following code in devise/encryptor.rb will return a different hashed password value than that stored in db:
password = ::BCrypt::Engine.hash_secret(password, bcrypt.salt)
As the result, Devise.secure_compare will return false. Once I restart the browser, I would be able to successfully sign in, as the hashed value returned by ::Bcrypt::Engine.hash_secret() will then be identical to encrypted_password in the User model.
Stepping through self.compare(klass, hashed_password, password) in Decryptor:
# arguments
> hashed_password
=> "$2a$12$yhr1pRFrdWTeYzCeuJCnA.tibFxeQK.4jdzRa5jpi28jQp.lB67u."
> password
=> "nxuBdUiS6wjZUQq"
bcrypt = ::BCrypt::Password.new(hashed_password)
> bcrypt
=> "$2a$12$yhr1pRFrdWTeYzCeuJCnA.tibFxeQK.4jdzRa5jpi28jQp.lB67u."
> bcrypt.salt
=> "$2a$12$yhr1pRFrdWTeYzCeuJCnA."
password = ::BCrypt::Engine.hash_secret(password, bcrypt.salt)
> password
=> "$2a$12$yhr1pRFrdWTeYzCeuJCnA.GlmoiuIfYRwdtdU3vAVPvr9wOmoClqu"
Devise.secure_compare(password, hashed_password)
=> false
I am trying to understand how expired sessions affect the hashed password value returned by ::BCrypt::Engine.hash_secret(), but nothing comes to mind!
Expected behavior
password = ::BCrypt::Engine.hash_secret(password, bcrypt.salt)
> password
=> "$2a$12$yhr1pRFrdWTeYzCeuJCnA.tibFxeQK.4jdzRa5jpi28jQp.lB67u."
@aeigus We are experiencing a similar issue at the moment, so far I traced it back to this since I know for sure some affected users are always using the valid password.
Do you have more info about this and the potential fix?
If I remember correctly, I could do nothing to solve the issue, but it doesn't seem to appear for some time lately...