Buy my course: Security for Rails Developers.
A pull request on Rails and Devise triggered me to write this blogpost.
Password strength is more complicated than length and the enforcement of various characters, because passwords like “Admin123!” can meet certain requirements, like containing different cases, 3 digits and a special character, but can be still cracked in no time and would fall for a dictionary attack even quicker.There are plenty of resources online explaining this, so I will not repeat them.
Luckily, there is an open-source password strenght estimator that works via pattern matching and does a pretty good job at flagging easy to crack passwords: zxcvbn. There is a Ruby implementation too of the tool and that makes it easy to validate the strenght of a password.
You just need to add the gem to your app with bundle:
bundle add zxcvbn-ruby
Then you can add a validator to your user model as follows:
require 'zxcvbn'
class User < ApplicationRecord
validate :password_strength
def password_strength
if password.present?
result = Zxcvbn::Tester.new.test(password)
if result.feedback.suggestions.any?
errors.add :password, result.feedback.suggestions.join(' ' )
end
end
end
end
I suggest to additionally validate the passwords with the pwned gem, to make sure they were not in a data breach. Doing so is also pretty simple.
You need to add the gem to the Gemfile:
bundle add pwned
And you can use the custom Rails validator from the gem:
class User < ApplicationRecord
# ...
validates :password, not_pwned: true
end
By adding these two validations, you will enforce way stronger passwords then if you just require the presence of certain characters.
Or follow me on Twitter
I run an indie startup providing vulnerability scanning for your Ruby on Rails app.
It is free to use at the moment, and I am grateful for any feedback about it.If you would like to give it a spin, you can do it here: Vulnerability Scanning for your Ruby on Rails app!