How do I enforce stronger password requirements on my Craft site?
In Craft 2

Plugins have the power to enforce stricter password requirements using the users.onBeforeSetPassword event.

Add this code to your plugin’s primary class:

public function init()
{
    craft()-&gt;on('users.beforeSetPassword', array($this, 'onBeforeSetPassword'));
}

public function onBeforeSetPassword(Event $e)
{
    $user = $e-&gt;params['user'];
    $password = $e-&gt;params['password'];

    // Perform our custom validation logic here
    $validates = true;

    if (mb_strlen($password) &lt; 7)
    {
        $validates = false;
    }
    else if (!preg_match('/(\d.*[A-Z]|[A-Z].*\d)/', $password))
    {
        $validates = false;
    }

    if (!$validates)
    {
        // Set $performAction = false so the password doesn't get saved
        $e-&gt;performAction = false;

        // Add a custom validation error on the user
        $user-&gt;addError('newPassword', 'Sorry but your password must contain an uppercase letter, a number, a haiku, a gang sign, hieroglyph, and the blood of a virgin.');
    }
}


In Craft 3

Craft 3 doesn't have a beforeSetPassword event, but you can pull the same thing off from your plugin's init() method using the User element's User::EVENT_BEFORE_VALIDATE event like so:

public function init()
{
    parent::init();

    Event::on(
        User::class,
        User::EVENT_BEFORE_VALIDATE,
        function (ModelEvent $event) {
            // Check if a new password was set on the user
            if ($event-&gt;sender-&gt;newPassword) {
                $password = $event-&gt;sender-&gt;newPassword;
                $errors = [];

                // Perform our custom validation logic here
                $validates = true;

                if (mb_strlen($password) &lt; 7) {
                    $validates = false;
                    $errors[] = 'Too Short!';
                }
                else if (!preg_match('/(\d.*[A-Z]|[A-Z].*\d)/', $password)) {
                    $validates = false;
                    $errors[] = 'Too Simple!';
                }

                $event-&gt;isValid = $validates;

                if (!$validates) {
                    /** @var User $user */
                    $user = $event-&gt;sender;
                    foreach ($errors as $error) {
                        $user-&gt;addError('newPassword', $error);
                    }
                }
            }
        }
    );
}