This week, I want to cover a common compliance requirement. If you ever went through a PCI, ISO 2007, SOC2, or similar compliance questionnaire, you found the following question in one form or another:
Use sufficiently strong and robust authentication methods to protect authentication credentials from being forged, spoofed, leaked, guessed, or circumvented.
Let’s see what we need to do to satisfy this requirement.
First of all, you must have a strong password policy.
I recommend asking for a minimum of 12 characters, with at least one uppercase letter and one number.
You can use Active Record validations for this. If you have a password attribute on your model, you can add a validation similar to this example:
validate :password_complexity
def password_complexity
if password.present? and !password.match(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{12,}$/)
errors.add :password, "must include at least one lowercase letter, one uppercase letter, one digit, and needs to be minimum 12 characters."
end
end
Additionally, you should validate that the password is not leaked. Luckily, there is a gem for that: https://github.com/philnash/pwned.
After installing the gem, All you need to do is add the following validation to the model:
validates :password, not_pwned: { on_error: :valid }
This will make a request to haveibeenpwned.com, mark the password as invalid if it has been pwned, and mark it as valid in case of a network or API error. You can find information about various configurations in the readme of the gem.
The final thing to prevent is credentials leaking. For this, you should store the passwords hashed with a robust hashing algorithm such as bcrypt.
That’s it for now. I will publish a longer form post tomorrow on my blog about securing authentication in Rails apps.
Did you enjoy reading this? Sign up to the Rails Tricks newsletter for more content like this!
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!