Weird issue with devise valid_password?

Ruby on-RailsDeviseRuby on-Rails-3.2

Ruby on-Rails Problem Overview


For the past 2 hours, I have been trying to debug a weird issue in devise which is not letting me login.

Here's the stuff I'm referring too:

password 
=> 'vinodsobale'

password == 'vinodsobale'
=> true

resource.valid_password?(password)

=> false

resource.valid_password?('vinodsobale')

=> true

Attaching the screenshot as well:

enter image description here Note: I have enabled debugger inside devise so the above code is devise internal code.

To me, it looks like a issue in Devise.secure_compare.

Ruby on-Rails Solutions


Solution 1 - Ruby on-Rails

This issue is due to a known string-corruption bug in Ruby 2.2.0 that was fixed in 2.2.2.

As described in the bug report, the corruption occured when BCrypt called a specific string-creation API from its C extension, which Devise v3.3.0 triggered by calling ::BCrypt::Engine.hash_secret from the Devise::Models::DatabaseAuthenticatable#valid_password? method. A Devise-specific workaround for this bug was published in v3.5.0.

The solution is to either:

  • Downgrade Ruby to < 2.2.0, or upgrade to >= 2.2.2;
  • Upgrade Devise to >= 3.5.0.

Solution 2 - Ruby on-Rails

How about

resource.valid_password?(password.to_s)

I hope it help You.

Solution 3 - Ruby on-Rails

Devise DatabaseAuthenticatable#valid_password? is using a method called Encryptor::compare it take 2 objects, the current stored password and the new password you want to compare, I believe there is a side effect for this method that modify the second parameter in the middle so it'll modify the object instead of once it'll be modified twice which leads to a false result, so it may work if you passed a duplicated object of password. can you try to use valid_password? password.dup

Solution 4 - Ruby on-Rails

It could be a problem with the encoding between the original source and your console. If you run password.codepoints, you should be able to see the actual encoding. Running .codepoints on the raw 'password' string should return [112, 97, 115, 115, 119, 111, 114, 100].

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionVirenView Question on Stackoverflow
Solution 1 - Ruby on-RailswjordanView Answer on Stackoverflow
Solution 2 - Ruby on-RailsСергій НазаревичView Answer on Stackoverflow
Solution 3 - Ruby on-RailsEmad ElsaidView Answer on Stackoverflow
Solution 4 - Ruby on-RailsTorrey PayneView Answer on Stackoverflow