Inform your users about breached passwords using Pwned Passwords API
Passwords one of the most frequent ways that we use to access our digital accounts. Having secure passwords is really crucial, and represents one of the most important aspects that we need to pay attention to. As developers, we also need to make sure that we provide our services with a high level of security. Last year 2017 NIST (National Institute of Standards and Technology) recommended to check user passwords against existing public breaches of data, and fortunately, there exists an API that allows you to do that really easily.
The Pwned Passwords API is a service that you can use to check whether a password has been exposed as part of a number of numerous data breaches that have occurred several times in the past. These data contain more than 500,000,000 passwords that have been used before.
You can install this in your Ruby applications using the following gem as a wrapper:
gem 'pwned'
After you have installed it, you can create a new this Pwned::Password object and then check if it has been breached:
password = Pwned::Password.new("password")
You can also check how many times the password appears in the dataset.
password = Pwned::Password.new("password")
password.pwned_count
#=> 3303003
As you may probably be using this service as part of the sign up process, you are supposed to also take into consideration the fact that this service may not be working sometimes:
begin
password = Pwned::Password.new("password")
password.pwned?
rescue Pwned::Error => e
# Ummm... don't worry about it, I guess?
end
You can also make this API call a lot easier using the following:
Most of the times you only care if the password has been pwned before or not. You can use simplified accessors to check whether the password has been pwned, or how many times it was pwned:
Pwned.pwned?("password")
#=> true
Pwned.pwned_count("password")
#=> 3303003
You can also validate your models like the following:
class User < ApplicationRecord
validates :password, not_pwned: true
# or
validates :password, not_pwned: { message: "has been pwned %{count} times" }
end
You can even set a threshold that you believe should be used to warn a user about a password that has been breached. For example, you may think that a password that has appeared only 2 times is not a problem:
class User < ApplicationRecord
# The record is marked as valid if the password has been used once in the breached data
validates :password, not_pwned: { threshold: 2 }
end
If you are using Devise for your authentication, there is another specific gem prepared specifically for this.
You can learn more about this gem and its implementation by visiting its Github page.