The Pwned Password validator checks the user's submitted password (in a registration or password change form) with the awesome
HIBP Pwned Passwords service to see if it is a known pwned password.
If the password has been pwned, it will fail validation, preventing the user from using that password in your app.
Pwned Passwords are half a billion real world passwords previously exposed in data breaches. This exposure makes them unsuitable for ongoing use as they're at much greater risk of being used to take over other accounts.
This uses the ranged search feature of the Pwned Passwords API, which uses k-anonymity
to significantly reduce the risk of any information leakage when accessing the API.
For most systems this should be more than secure enough, although you should definitely decide for yourself if it's suitable for your app.
You will need to assign your own validation message within the resources/lang/*/validation.php file(s).
Both the Rule object and the pwned validator alias refer to the validation string validation.pwned.
I haven't set a default language string as it is important you get the language right for your intended users.
In some systems a message like Your password has been pwned! Please use a new one! is suitable, while in other systems
you'd be better with something a lot longer:
You password is insufficiently secure as it has been found in known password breaches, please chose a new one. Need help?
Thanks to kanalumaddela, you can use :min in the message to indicate the minimum number of times found set on the validator.
Your password is insufficiently secure as it has been found at least :min times in known password breaches, please chose a new one.
Limiting by the number of times the password was pwned
You can also limit rejected passwords to those that have been pwned a minimum number of times.
For example, password has been pwned 3,303,003 times, however P@ssword! has only been pwned 118 times.
If we wanted to block password but not P@ssword!, we can specify the minimum number as 150 like this:
Q: How secure is this?
A: Please check the above linked blog posts by Troy Hunt and Cloudflare, as they will answer your question and help you decide if it's safe enough for you.
Q: Do you do any caching?
A: Yep! Each prefix query is cached for a week, to prevent constant API requests if the same prefix is checked multiple times.
Q: Where are the tests?
A: To properly test this code, we need to hit the web service. I don't want to automate that, to avoid abusing this fantastic service. Instead, since it is an incredibly simplistic validator, I've opted to manually test it for now.