Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preventing password reuse with Devise

I know that forcing passwords to expire after a certain period from the time the user creates them is not part of Devise logic, and I'm planning to write my own code to make that happen.

It also looks like forcing the user not to reuse one of the last X (in my case 10) passwords will need to be coded manually.

My thinking is that I'll create something like a user_passwords table and use logic in my code to make sure the new password doesn't match any in that table for that user. At the same time I would insert the new password into the table, unless there are 10 records for that user there already, which would mean I'd overwrite the oldest with the new value. Table structure would be something like this:

user_passwords

  • user_id
  • encrypted_password
  • created_at

If anyone has a better, more elegant solution to handle this, I'd appreciate it.

like image 607
yuяi Avatar asked Jan 17 '23 13:01

yuяi


2 Answers

I know that forcing passwords to expire after a certain period from the time the user creates them is not part of Devise logic, and I'm planning to write my own code to make that happen.

In practice, the security related studies have found this to be a bad idea. That's because you get diminishing returns on each change. That is, the password starts strong and then gets weaker over time as the user attempts to comply with the policy. See Peter Gutmann's Engineering Security and Chapter 7, Passwords.

From the book, other dumb things include complexity requirements. (Before you object, read the relevant section of the book).


... create something like a user_passwords table and use logic in my code to make sure the new password doesn't match any in that table for that user.

And once you read the chapter, I will be able to ask: why did you allow the user to choose a weak/wounded/broken password in the first place? Those 60 KB Bloom filters are looking mighty useful when combined with Mark Brunett's list of 10 million leaked passwords :)


Preventing password reuse...

The reuse that's going to hurt is password reuse across sites. Brown, Bracken, Zoccoli and Douglas state the numbers are around 70% in Generating and Remembering Passwords (Applied Cognitive Psychology, Volume 18, Issue 6, pp. 641–651). And Das, Bonneau, Caesar, Borisov and Wang report the number around 45% in The Tangled Web of Password Reuse. Note the the Tangled Web study had to crack passwords, so that number is likely higher because they were not able to recover all the passwords

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

I even got burned with this one a few years ago. I used the same password on two low value accounts. Then GNU's Savannah got hacked and the attackers were able to use the recovered password to breach a little used email account.

Now I just generate a long, random string when I need credentials. I don't even bother writing them down for most sites. When I need to access a site again, I just go through the recovery process.

like image 189
jww Avatar answered Jan 29 '23 14:01

jww


The devise_security_extension seems to work for what I need.

However, at present, it doesn't support Devise 2.0 or higher. I ran into a number of issues, and had to downgrade my Devise to 1.5.3. According to comments on their message board, they're currently working on porting the gem to a Devise 2.0 compatible version.

I have given it a spin for its password_expirable and password_archivable modules. Everything seems to work as expected.

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

like image 20
yuяi Avatar answered Jan 29 '23 15:01

yuяi