Security Tip: Default Password Rules

[Tip#11] Why duplicate password validation rules across your app when you can define defaults once?

Security Tip: Default Password Rules

⚠️ Need a security audit but don't have the budget for a full penetration test? Book in a Laravel Security Review! 🕵️

🤓 Learn to Think Like a Hacker with my hands-on practical security course: Practical Laravel Security! 🕵️


Password Rules are typically defined on a project or company level and then reused across an app, so you’ll probably find yourself copy-pasting the rules from one validator to another when building registration, password change, etc, and then if the rules ever change1, you’ll have to bounce between all of the validators to update the rules. It doesn’t sound that hard, but it still takes effort, and if your app has multiple logins or registration forms, you’ll need to update and all of them…

Luckily for us, Laravel makes this easy!2

Laravel’s Password Validator includes the concept of Default Password Rules. You use it by defining your password rules once, usually in a Service Provider, and then you can simply refer to these rules in each validator as `Password::defaults()`.

Let’s define a basic minimum length and mixed-case rule:

use Illuminate\Validation\Rules\Password;

class AppServiceProvider extends ServiceProvider
{
    // ...

    public function boot()
    {
        Password::defaults(fn () => Password::min(8)->mixedCase());
    }
}

The validator can then look like this:

'password' => ['required', Password::defaults()],

Now we can change our password rules, and the validator won’t change at all.

It also lets us customise the password validator easily, such as blocking pwned passwords in production3, as per the Laravel documentation:

use Illuminate\Validation\Rules\Password;

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        Password::defaults(function () {
            $rule = Password::min(8);

            return $this->app->isProduction()
                ? $rule->mixedCase()->uncompromised()
                : $rule;
        });
    }
}

That’s it. 👋


  1. Most likely triggered by some external security audit, or compliance checklist.

  2. As we would expect. 🙂

  3. I’ll dive into this in detail in a future email, but just a quick note: I don’t recommend validating pwned passwords with a non-technical user base without also spending time on user education. You need to help your users pick better passwords, not simply block bad ones and hope they figure it out themselves.