Security Tip: Should You Block Compromised Passwords?

[Tip#13] Blocking Compromised (Pwned) Passwords forces your users to use strong passwords, but is it the right choice for your app?

Security Tip: Should You Block Compromised Passwords?

Passwords are the digital keys that keep user accounts safe, but passwords only work when they are secret and unguessable. The classic “fix” is to impose password complexity rules, but who here hasn’t simply added a 1 or ! (or both) onto the end of the password they wanted to use?

Password complexity rules and complexity indicators are superficial fixes that don’t solve the root problem: users are lazy and reuse the same passwords everywhere.

The problem with reusing passwords is simple: If user reuses the same password on multiple sites (i.e. A, B, & C) and site A is compromised and has stored passwords insecurely, the hacker now has a working username:password combination to use on site’s B & C.

These passwords are known as Compromised or “Pwned” Passwords.

To prevent users from using compromised passwords, we can use the excellent Pwned Passwords service by Troy Hunt, which aggregates passwords from data breaches and provides a secure way to check if passwords have been pwned or not.

🤓
Despite all of the security advice of “Never provide your password to a third-party”, the Pwned Passwords service is safe and secure and you can use it to check passwords. More information...

The Laravel Password Validation Rule comes with an uncompromised() method, which we can use to easily validate passwords and prevent the use of pwned/compromised passwords when users create accounts or change passwords:

 $validator = Validator::make($request->all(), [
    'password' => [
        'required', 
        'confirmed', 
        Password::min(8)->uncompromised()
    ],
]);

It’s super simple to use, so there’s no reason not to use it… right?

There’s always a but…

You can’t simply add the uncompromised() rule into your validator and consider the job done. When the validator fails on user registration, this is the message your users will see:

'The given :attribute has appeared in a data leak. Please choose a different :attribute.'

If your audience are all technical folks, they should know what a “data leak” is and why passwords are important, so this message will probably make them laugh and they’ll pick a new password. Job done. 👍

But what if they are non-technical? They might not know what a “data leak” is, or how to use a password manager, and they may reuse the same password everywhere. If they hit this message, there is a good chance they’ll simply go elsewhere and find one of your competitors (with worse security!) to sign up for with their terrible password.

Don’t get me wrong, I’m not saying you shouldn’t use the uncompromised() password rule, but I think you need to take it a step further. We need to encourage our users to use secure passwords, and to do so, we need to teach them what a secure password is.

Educate Your Technical Users

If your users are technical, you can expand on the validation message to provide links to resources like Pwned Passwords and extra FAQ entries. This is something that Stefán Jökull Sigurðarson did at EveOnline very successfully:

Help Your Non-Technical Users

If your users are non-technical, maybe make it soft-fail, and allow them to use a pwned password but add extra authentication steps in or provide information for them to read about passwords and encourage them to update their password. In addition, a magic link sent via email is easy second layer of authentication you could employ to keep their accounts safe, and shifts the burden of authentication onto their email providers - who likely have much bigger security budgets than you!

Finally, don’t forget that SMS-based Multi-Factor Authentication is not insecure. It’s far more secure than using a password on it’s own, and it’s also incredibly accessible for non-technical users who wouldn’t know where to start with a authentication app. So don’t be afraid to implement SMS MFA as an option!

💡
SMS MFA attacks are specifically targeted against high value targets, and take significant effort, so it is still more secure than no MFA at all for normal users. Plus, the “SMS MFA” insecurity is often an insecure password reset that bypasses the password entirely anyway.

You should definitely offer app-based MFA (TOTP), and Passkeys as MFA options too, as these are more secure than SMSes, but don't reject SMSes without considering their benefits for non-technical users.

Found this security tip helpful? Don't forget to subscribe to receive new Security Tips each week, and upgrade to a premium subscription to receive monthly In Depth articles, or toss a coin in the tip jar.

Reach out if you're looking for a Laravel Security Audit and Penetration Test or a budget-friendly Security Review, and find me on the various socials through Pinkary. Finally, don't forget to check out Practical Laravel Security, my interactive security course.