Prevent Password Reuse with Devise

I know that forcing passwords to expire after a certain period from the moment the user creates it is not part of the Devise logic, and I plan to write my own code for this to happen.

It also seems to force the user not to use one of the last X (in my case 10) passwords must be manually encoded.

I believe that I am creating something like a user_passwords table and use the logic in my code to make sure that the new password does not match any one in this table for this user. At the same time, I would enter a new password in the table if there were already no 10 entries for this user, which would mean that I would rewrite the oldest with a new value. The structure of the table will be something like this:

user_passwords

  • user_id
  • encrypted_password
  • created_at

If anyone has a better, more elegant solution to solve this issue, I would appreciate it.

+4
source share
4 answers

devise_security_extension seems to work for what I need.

However, it does not currently support Devise 2.0 or higher. I ran into a number of problems and had to downgrade my Devise to 1.5.3. According to the comments on their bulletin board, they are currently working on porting the gem to a version compatible with Devise 2.0.

I gave him a spin for my file passwords requiring a password and passwords. Everything seems to work as expected.

It also supports secure_validatable, session_limitable and expirable, the first 2 of which I will probably use in the near future.

+2
source

I know that forcing passwords to expire after a certain period from the moment the user creates it is not part of the Devise logic, and I plan to write my own code for this to happen.

In practice, security studies have shown this to be a bad idea. This is because you reduce the return on each change. That is, the password starts strong, and then becomes weaker over time, as the user tries to execute the policy. See Peter Gutmann Engineering Security and Chapter 7, Passwords.

From the book, other stupid things include complexity requirements. (Before objecting, read the relevant section of the book).


... create something like a user_passwords table and use the logic in my code to make sure that the new password does not match any one in this table for this user.

And as soon as you read the chapter, I can ask: why did you allow the user to choose a weak / wounded / broken password in the first place? These 60 KB Bloom filters look very useful when combined with Mark Brunett containing 10 million missing passwords :)


Password Reuse Prevention ...

Reuse that could damage - reuse of passwords on sites. Brown, Bracken, Zokkoli, and Douglas state that numbers make up about 70% in Password Generation and Storage (Applied Cognitive Psychology, Volume 18, Issue 6, pp. 641-651). And Das, Bonno, Caesar, Borisov, and Van all report about 45% in The Tangled Web of Password Reuse . Note that the Tangled Web study was supposed to crack passwords, so the number is probably higher because they could not recover all the passwords.

To make reuse a more acute problem, users need to remember passwords for about 25 different sites according to Das, Bonneau, Caesar, Borisov and Wang in The Tangled Reuse of Web Password .

I even burned out with this a few years ago. I used the same password for two low value accounts. Then, GNU Savannah was hacked, and attackers were able to use the recovered password to violate an under-used email account.

Now I just create a long random string when I need credentials. I don’t even bother them for most sites. When I need to access the site again, I just take the recovery process.

+4
source

Here is the documentation for decorating Devise for How to prevent the use of previously used passwords?

0
source

devise_security_extension does not work for me in rails 5, I created my custom:

  • create a migration and add an additional column, for example: add_column: users ,: old_passwords ,: text
  • In your model, add two callbacks: after_save: cache_old_pass and before_save: verify_old_pass

  • Create callback methods:

    private def verify_old_pass if self.encrypted_password_changed? old_passwords.to_s.split(',').each do |pass_encrypted| if Devise::Encryptor.compare(self.class, pass_encrypted, password) errors.add(:base, 'Your password cannot be previous up to 3 back') return throw(:abort) end end end end def cache_old_pass # cache last 3 passwords if self.encrypted_password_changed? update_column(:old_passwords, ([self.encrypted_password] + old_passwords.to_s.split(',')[0, 3]).join(',')) end end 
-one
source

Source: https://habr.com/ru/post/1395332/


All Articles