How to customize/override the user password validation?

Hello,

I tried to find out how I can customize/override the user password validation process but I didn’t find a proper function to override. I found these 3 at https://getkirby.com/docs/reference/objects/user?advanced=yes :

None of these 3 validates the password according to the criterias when you want to change the current password of an user. I also checked the validators but there is no user password validator. So what do I have to override to apply custom password rules like length, special characters, etc.?

Is the proper way to use a user.changePassword:before hook and then throw an exception if the new password doesn’t fulfills the criterias to prevent the password change?

A general question about hooks: Are hooks used by Kirby 3’s core or are they non-implemented? Like does Kirby 3 use any hook itself or are they just provided for the customers/developers of customer projects? I’m asking because I think that’s the only place left I could look at to find the validation of Kirby 3 user passwords but I don’t find any source code of the hook if I search for changePassword, user.changePassword or user.changePassword:before via Github’s repository search and thus I’m not sure about this.

Best Regards,

Length validation for the changePassword() method happens here

    {
        if (Str::length($password ?? null) < 8) {
            throw new InvalidArgumentException([
                'key' => 'user.password.invalid',
            ]);
        }

        return true;
    }

(/kirby/src/Cms/UserRules.php)

I don’t know if there is a way to override these methods, though. The only way I can think of is via a user model, but that would be role based, not in general.

Or you can implement your own login view with your own authentication methods: https://getkirby.com/docs/reference/plugins/extensions/panel-login

1 Like

Is there a reason why a hook like I described wouldn’t work? It’s fine if the 8 chars minimum password validation still kicks in because the password strength validation will be stronger than looser so > 8 chars. I suspect I misunderstand the way I can use hooks in this case like my idea wouldn’t work at all.

An own login view seems overkill if I like to share the results with third parties as a plugin.

What I try to achieve: I want to enforce a specific length with at least one special character and then I would like to validate the password against the Have I been Pwned API to prevent weak passwords: https://haveibeenpwned.com/API/v2#SearchingPwnedPasswordsByRange

The need for this is because Kirby 3 offers zero bruteforce protection and this has been a known successful attack scenario in the past and I prefer a secure authentication over some htaccess or firewall rules. The panel has to be usable (I can’t disable it in my use case). So I think implementing better passwords is easier than implementing a bruteforce protection in Kirby 3.

That’s not quite true, because after each wrong try Kirby sleeps a while and also, it tracks invalid login trials and blocks an IP after 10 wrong trials (default setting, can be changed in config).

But yes, a route before hook could work.

1 Like

I’m surprised @texnixe! Is this at all documented somewhere? I found nothing in the references, the security guide (which then contains a misleading sentence about bruteforcing Kirby 3) and only outdated posts on this then. I did some research in the past before I wanted to do this and I found zero information about this.

Edit: I found this How does Kirby 2.2 bruteforce protection work? and Is Kirby secure?. Seems like the first time I didn’t find the first thread. Seems like there is a bruteforce protection beginning to ban after 5 (?) tries. At least it triggered before 10 times.

Is there any update on this topic? It would be really helpful if there would be an option to easily be able to change password rules. Strict password policies are a common request by customers we are working for.

You would have to overwrite the validatePassword() method in a custom user class.