# Using the chain-of-responsibility pattern to hash WordPress passwords

"[Passwords Evolved](https://wordpress.org/plugins/passwords-evolved/)" is an open source WordPress plugin that I've built and maintained over the years. It's a security plugin that prevents someone from using a password that has appeared in a data breach. To do that, it leverages the "[Have I Been Pwned?](https://en.wikipedia.org/wiki/Haveibeenpwned)" API to check if the password you're using was found in a breach. The plugin also changes the [hashing function](https://en.wikipedia.org/wiki/Cryptographic_hash_function) used to hash WordPress passwords. Initially, the plugin only supported the [bcrypt](https://en.wikipedia.org/wiki/Bcrypt) hashing function. This hashing function has been standard since PHP 5.5. Since PHP 7.0, it's been possible to hash passwords using a newer function called [Argon2](https://en.wikipedia.org/wiki/Argon2). Argon2 is available natively since PHP 7.2. Before that, you had to use the [libsodium](https://download.libsodium.org/doc/) library to use Argon2 with PHP. There's also a libsodium compatibility layer [starting in WordPress 5.2](https://wptavern.com/wordpress-5-2-improves-the-security-of-automatic-updates). Checking for and using all these different hashing functions sounds like a headache waiting to happen. But, in fact, it's not that hard to design a set of classes to handle all these different cases. The "[Chain-of-Responsibility](https://en.wikipedia.org/wiki/Chain-of-responsibility_pattern)" pattern was created for situations such as this one.

# What is the "Chain-of-Responsibility" pattern?

So "Chain-of-Responsibility" sounds like a mouthful, but it's not too complicated in practice. A good analogy for it is the `if ... elseif ... elseif` [conditionals](https://carlalexander.ca/mastering-php-conditionals/) chain. The "Chain-of-Responsibility" pattern is basically the object-oriented version of that chain. (Thus the name!) So that's the idea with the "Chain-of-Responsibility" pattern. You have a chain of objects. And whenever you want to perform an operation on some input, you pass it to that chain. The chain will pass it from one object to the next until one of them can perform an operation on it. Just like you would with that `if ... elseif ... elseif` chain. ![](https://d3nw5tt5i784nr.cloudfront.net/uploads/2020/02/chain-of-responsibility-diagram-1024x458.png)The diagram above shows the chain in action. The chain has three objects, and the input passes from object to object. But since the second object decides to perform an action on the input, the third object never gets to interact with it. This highlights the big difference between the "Chain-of-Responsibility" pattern and the better-known [decorator pattern](https://carlalexander.ca/wordpress-decorator-pattern/). With the decorator pattern, every object gets to interact and "decorate" the input. It's not just one object that gets to interact with it. Besides this, both patterns work nearly identically. So, if you're already familiar with the decorator pattern, the inner workings of the “Chain-of-Responsibility” pattern won’t surprise you. Both patterns have a similar implementation. # Starting with an interface

The core element of this implementation of the "Chain-of-Responsibility" pattern is going to be [an interface](https://carlalexander.ca/polymorphism-wordpress-interfaces/). For the "Passwords Evolved" plugin, that interface was the `PasswordHasherInterface` interface. Here's a look at it: ```
/**
 * A password hasher hashes a password using a hashing algorithm.
 */
interface PasswordHasherInterface
{
    /**
     * Hashes the given password. Returns null if unable to hash password.
     *
     * @param string $password
     *
     * @return string|null
     */
    public function hash_password($password);

    /**
     * Checks if the password hasher supports the given hash for verification.
     *
     * @param string $hash
     *
     * @return bool
     */
    public function is_hash_supported($hash);

    /**
     * Checks if the given hash is valid. If a hash is invalid, we need to rehash it.
     *
     * @param string $hash
     *
     * @return bool
     */
    public function is_hash_valid($hash);

    /**
     * Validates that the given password matches the given hash.
     *
     * @param string $password
     * @param string $hash
     *
     * @return bool
     */
    public function is_password_valid($password, $hash);
}
```

The `PasswordHasherInterface` (shown above) has four methods. Three of them perform actions on a hash value or password. These are the inputs that we described earlier. Those three action-performing methods are the `hash_password`, `is_hash_valid` and `is_password_valid` methods. The `hash_password` method takes a `password` turns it into a hash value. The `is_hash_valid` method checks if the given hash value is a valid `hash` value or not. The `is_password_valid` method checks if the given `password` is valid for the given `hash` value. The fourth method in the `PasswordHasherInterface` interface is the `is_hash_supported` method. This method is central to this implementation of the "Chain-of-Responsibility" pattern. It's the method used to determine if our object in the chain can perform actions on the given `hash`. Whenever you use any of the three action-performing methods, the chain will start calling the `is_hash_supported` method on all the objects in the chain. The first object in the chain that returns `true` will be the one selected to perform the requested action. The value returned by the action is the one returned by the chain. # Creating some password hashers

Now that we have the `PasswordHasherInterface` interface, we can move on to designing our classes. Before we create our chain, we'll create some password hashers that we can use with it. For this article, we'll create two. ## WordPress password hasher

The first password hasher that we'll create will hash passwords using WordPress's built-in `PasswordHash` class. We're going to call it `WordPressPasswordHasher`. You can see the code for it below. ```
/**
 * Password hasher that uses the builtin WordPress password hasher.
 */
class WordPressPasswordHasher implements PasswordHasherInterface
{
    /**
     * WordPress password hasher.
     *
     * @var \PasswordHash
     */
    private $wordpress_hasher;

    /**
     * Constructor.
     *
     * @param \PasswordHash $wordpress_hasher
     */
    public function __construct(\PasswordHash $wordpress_hasher)
    {
        $this->wordpress_hasher = $wordpress_hasher;
    }

    /**
     * {@inheritdoc}
     */
    public function hash_password($password)
    {
        return $this->wordpress_hasher->HashPassword($password);
    }

    /**
     * {@inheritdoc}
     */
    public function is_hash_supported($hash)
    {
        return 0 === strpos($hash, '$P$');
    }

    /**
     * {@inheritdoc}
     */
    public function is_hash_valid($hash)
    {
        return false;
    }

    /**
     * {@inheritdoc}
     */
    public function is_password_valid($password, $hash)
    {
        return $this->wordpress_hasher->CheckPassword($password, $hash);
    }
}
```

### Wrapper methods

The `WordPressPasswordHasher` class is just a wrapper around the `PasswordHash` class. This means that, for a lot of `PasswordHasherInterface` methods, we're just going to call a `PasswordHash` method. (This is why it's a good example of the [adapter pattern](https://en.wikipedia.org/wiki/Adapter_pattern)!) Because of that, the `WordPressPasswordHasher` constructor will just take a `PasswordHash` object as an argument. We then assign it to the `wordpress_hasher` class property. Next, let's look at the implementations of the `PasswordHasherInterface` methods. Two of them call a method on the `PasswordHash` object stored inside our `WordPressPasswordHasher` object. There's `hash_password` which calls the `HashPassword` method of the `PasswordHash` object. And then there's `is_password_valid` which calls the `CheckPassword` method. The two more interesting methods to discuss are `is_hash_supported` and `is_hash_valid`. The `is_hash_supported` method uses the [`strpos`](https://www.php.net/manual/en/function.strpos) function to check if a hash starts with `$P$`. But what does `$P$` mean and why are we looking for it? The reason why we look for `$P$` is because of how hash functions work. Each function will prefix a hash value that it generates. That way, you can tell it created the hash value. For the `PasswordHash` class, that prefix is `$P$` and that's why we're looking for it. The last method is `is_hash_valid`. You might be wondering why it returns `false` without even looking at the hash value. This is intended because of what the plugin wants to do. It wants WordPress passwords to use a stronger hashing function. So by always returning `false`, we're forcing the plugin to discard any hash value created by the `PasswordHash` class. Instead, the plugin will have to rehash the password using a stronger hashing function. This might seem weird but it'll make more sense once we go over how the "chain" works later in the article. ## Native password hasher

For the second password hasher, we're going to use [PHP's native password hashing functions](https://www.php.net/manual/en/ref.password.php). These functions can use different hashing algorithms such as Argon2. But by default, they use bcrypt. As for the class, we'll name it `NativePasswordHasher`. It'll also implement the `PasswordHasherInterface` interface. (All classes in the chain should.) Here's what the code for the class. ```
/**
 * Password hasher that uses the native PHP password hashing functions.
 */
class NativePasswordHasher implements PasswordHasherInterface
{
    /**
     * Algorithm used when hashing a password.
     *
     * @var int
     */
    private $algorithm;

    /**
     * Constructor.
     */
    public function __construct()
    {
        $this->algorithm = PASSWORD_DEFAULT;

        if (defined('PASSWORD_ARGON2ID')) {
            $this->algorithm = PASSWORD_ARGON2ID;
        } elseif (defined('PASSWORD_ARGON2I')) {
            $this->algorithm = PASSWORD_ARGON2I;
        }
    }

    /**
     * {@inheritdoc}
     */
    public function hash_password($password)
    {
        return password_hash($password, $this->algorithm);
    }

    /**
     * {@inheritdoc}
     */
    public function is_hash_supported($hash)
    {
        if (0 === strpos($hash, '$argon2id$')) {
            return defined('PASSWORD_ARGON2ID');
        } elseif (0 === strpos($hash, '$argon2i$')) {
            return defined('PASSWORD_ARGON2I');
        }

        return 0 === strpos($hash, '$2');
    }

    /**
     * {@inheritdoc}
     */
    public function is_hash_valid($hash)
    {
        return !password_needs_rehash($hash, $this->algorithm);
    }

    /**
     * {@inheritdoc}
     */
    public function is_password_valid($password, $hash)
    {
        return password_verify($password, $hash);
    }
}
```

### Choosing an algorithm

The interesting part of the `NativePasswordHasher` class is the constructor. This is where we're going to choose the hashing algorithm used by the class. We'll store that hashing algorithm value in the `algorithm` class property. Choosing the algorithm is simply a question of detecting [PHP password constants](https://www.php.net/manual/en/password.constants.php) using the [`defined`](https://www.php.net/manual/en/function.defined) function. By default, we're going to assign the `PASSWORD_DEFAULT` constant value to the `algorithm` property. This constant stores the default hashing algorithm used by PHP. At this time, this default algorithm is bcrypt. We could have also just used its constant called `PASSWORD_BCRYPT` instead. But, either way, both `PASSWORD_DEFAULT` and `PASSWORD_BCRYPT` are identical. The rest of the constructor is just two guard clauses. They check if PHP supports one of the two possible Argon2 hashing algorithms. If PHP does, we change the value of the `algorithm` property. The first constant that we look for is `PASSWORD_ARGON2ID`. This is the preferred Argon2 hashing algorithm. That said, it's only available starting with PHP 7.3. So, to support PHP 7.2, we check for the `PASSWORD_ARGON2I` constant as well. ### Using the algorithm

Now that we set the `algorithm` class property, we can look at how we use it in the `NativePasswordHasher` class. The two methods that make use of it are the `hash_password` and `is_hash_valid` methods. Both use the `algorithm` class property as the second argument of a PHP password function. These two functions are [`password_hash`](https://www.php.net/manual/en/function.password-hash.php) and [`password_needs_rehash`](https://www.php.net/manual/en/function.password-needs-rehash.php). The `hash_password` method uses the `password_hash` function to create a hash value using our chosen algorithm. Meanwhile, the `is_hash_valid` uses the `password_needs_rehash` function to check if a hash value is valid for our chosen algorithm. ### Checking the hash

The last two methods don't use the algorithm. The `is_hash_supported` method is very similar to the one in the `WordPressPasswordHasher` class. We use it to check if the `NativePasswordHasher` supports the given hash value. The `is_hash_supported` method is a bit more complex than the one in the `WordPressPasswordHasher` class. That's because we have to check for three hash prefixes. Two prefixes are for the two Argon2 algorithms and the third one is for bcrypt. Checking if we support Argon2 algorithms is done in two steps. First, we check if the hash value contains the algorithm prefix. If it does, we check if the password constant is defined using the `defined` function. If we get to the end of the method, we check for the bcrypt prefix only since it's the default algorithm. Verifying the password also doesn't require the `algorithm` class property. All that you have to do is pass the `password` and `hash` value to the [`password_verify`](https://www.php.net/manual/en/function.password-verify.php) password function. `password_verify` will figure out which algorithm to use by checking the hash value prefix like we've been doing. # Designing the chain

Now that we have some password hashers, we can move on to designing our chain. We're going to call it `PasswordHasherChain`. Unlike our password hashers, we're going to take a bit more time explaining the design of the class. ```
/**
 * Manages a chain of password hashers.
 */
class PasswordHasherChain implements PasswordHasherInterface
{
}
```

But first, let's start by creating the empty `PasswordHasherChain` class. It implements the `PasswordHasherInterface` interface that our password hashers also implement. The fact that all these classes share the same interface is one of the most crucial aspects of the design. ## Constructor

To begin, we're going to add the constructor to our `PasswordHasherChain`. ```
/**
 * Manages a chain of password hashers.
 */
class PasswordHasherChain implements PasswordHasherInterface
{
    /**
     * The password hashers that the chain handles.
     *
     * @var PasswordHasherInterface[]
     */
    private $password_hashers;

    /**
     * Constructor.
     *
     * @param PasswordHasherInterface[] $password_hashers
     */
    public function __construct(array $password_hashers = [])
    {
        $this->password_hashers = $password_hashers;
    }

    // ...
}
```

You can see above that the constructor has a single parameter called `password_hashers`. We assign it to a class property also called `password_hashers`. We [type hinted](https://www.php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration) the `password_hashers` constructor parameter as an `array` with a default of an empty array. ### More type safety

The problem with an `array` type hint is that it doesn't give us a lot of [type safety](https://en.wikipedia.org/wiki/Type_safety). The `password_hashers` array can contain any type of value. But we want it to contain only `PasswordHasherInterface` objects. So we're going to add some extra [type safety](https://en.wikipedia.org/wiki/Type_safety) to our constructor. We're going to do that by running the `password_hashers` array through an [array function](https://carlalexander.ca/php-array-functions-instead-loops/). For what we're trying to do, that array function will be the [`array_filter`](https://www.php.net/manual/en/function.array-filter.php) function. ```
/**
 * Manages a chain of password hashers.
 */
class PasswordHasherChain implements PasswordHasherInterface
{
    /**
     * The password hashers that the chain handles.
     *
     * @var PasswordHasherInterface[]
     */
    private $password_hashers;

    /**
     * Constructor.
     *
     * @param PasswordHasherInterface[] $password_hashers
     */
    public function __construct(array $password_hashers = [])
    {
        $this->password_hashers = array_filter($password_hashers, function ($password_hasher) {
            return $password_hasher instanceof PasswordHasherInterface;
        });
    }

    // ...
}
```

Above is the updated `PasswordHasherChain` constructor using the `array_filter` function. The `array_filter` function will remove all array elements that our `callback` returns `false` for. Here, that `callback` is an [anonymous function](https://www.php.net/manual/en/functions.anonymous.php). This anonymous function receives a `password_hasher` as an argument. It'll then determine whether `password_hasher` is an instance of `PasswordHasherInterface` or not. It does this by using the [`instanceof`](https://www.php.net/manual/en/language.operators.type.php) operator. The operator will return `true` if `password_hasher` is an instance of `PasswordHasherInterface`. Otherwise, it'll return `false`. We assign the array returned by the `array_filter` function to `password_hashers` array class property like before. But now, we're sure that the array only contains `PasswordHasherInterface` objects. This will allow us to use it without worrying that there might be invalid data in it. ## Selecting a password hasher

The use of the `array_filter` function in the `PasswordHasherChain` class constructor was really just the beginning. Now that we have a clean `password_hashers` array class property, we're going to use array functions with it as well! To begin, let's look at how we can select a `password_hasher` from the `password_hashers` array. ```
/**
 * Manages a chain of password hashers.
 */
class PasswordHasherChain implements PasswordHasherInterface
{
    // ...

    /**
     * Get the password hasher that supports the given hash.
     *
     * @param string $hash
     *
     * @return PasswordHasherInterface|null
     */
    private function get_password_hasher($hash)
    {
        return array_reduce($this->password_hashers, function ($found, PasswordHasherInterface $password_hasher) use ($hash) {
            if (!$found instanceof PasswordHasherInterface && $password_hasher->is_hash_supported($hash)) {
                $found = $password_hasher;
            }
            return $found;
        });
    }
}
```

The method that we're creating to do that is called `get_password_hasher`. The method that you can see above has a single parameter: `hash`. This is the hash value that we want the returned password hasher to support. ### Using array\_reduce to find a password hash

To find that password hasher, we're going to use the [`array_reduce`](https://www.php.net/manual/en/function.array-reduce.php) function. This array function reduces an array to a single value using a callback. The `callback` will again be an anonymous function. This anonymous function has two parameters: `found` and `password_hasher`. `found` is the current value that `array_reduce` would return if this was the last array item. `password_hasher` is the current password hasher from the `password_hashers` array that we're evaluating. Now, let's look at the code inside the anonymous function. It only contains a single conditional that we use to assign the `password_hasher` to the `found` variable. This conditional checks for two things. First, it checks if we found a password hasher already. We do that by checking if `found` is an object implementing the `PasswordHasherInterface`. The reason for this check is that we don't want to overwrite the `found` value if we already found a password harsher. If we still haven't found a password hasher, we move on to the second check. That's calling the `is_hash_supported` method of the given `password_hasher`. If the method returns `true`, we assign the `password_hasher` to the `found` variable and return it. Once `array_reduce` has finished going through the array of password hashers, it'll return one of possible two results. Either we found a password hasher, so the result is a class implementing the `PasswordHasherInterface` interface. Or it's `null` because we didn't find one. ## Using the get\_password\_hasher method

The `get_password_hasher` method is central to the `PasswordHasherChain` class. Two of the `PasswordHasherInterface` interface methods need us to find the correct password hasher for the given `hash` value. Those two methods are `is_hash_supported` and `is_hash_valid`. ```
/**
 * Manages a chain of password hashers.
 */
class PasswordHasherChain implements PasswordHasherInterface
{
    // ...

    /**
     * {@inheritdoc}
     */
    public function is_hash_supported($hash)
    {
        return $this->get_password_hasher($hash) instanceof PasswordHasherInterface;
    }

    /**
     * {@inheritdoc}
     */
    public function is_hash_valid($hash)
    {
        $password_hasher = $this->get_password_hasher($hash);

        if (!$password_hasher instanceof PasswordHasherInterface) {
            return false;
        }

        return $password_hasher->is_hash_valid($hash);
    }

    // ...
}
```

The `is_password_supported` method is quite simple. We call the `get_password_hasher` method. We then check the returned value using the `instanceof` operator. If the value returned by the `get_password_hasher` method is an instance of `PasswordHasherInterface` interface object, we return `true`. That's because we know the chain has a password hasher that supports the given `hash`. Otherwise, we return `false` because the `get_password_hasher` method returned `null`. The `is_hash_valid` method is similar to the `is_password_supported` method. We start by getting the password hasher for the given `hash` value using the `get_password_hasher` method. We then use the `instanceof` operator again. That's where the similarities end. We have to do a bit more than just use the `instanceof` operator in the `is_hash_valid` method. We only use the `instanceof` operator to validate if the `get_password_hasher` method returned a password hasher. If we don't have password hasher, we want to return `false` since we have no way to validate the `hash` value. If we do have a password hasher, we want to run the `hash` through the `is_hash_valid` method of the password hasher. We then pass back the return the value from the password hasher as the return value from our `is_hash_valid` method. ## Working with passwords

So far, we've only touched methods that dealt with the `hash` value. This is what we built the `get_password_hasher` method for. The two other methods of the `PasswordHasherChain` that we want to look at are for passwords. ```
/**
 * Manages a chain of password hashers.
 */
class PasswordHasherChain implements PasswordHasherInterface
{
    // ...

    /**
     * {@inheritdoc}
     */
    public function hash_password($password)
    {
        $hash = array_reduce($this->password_hashers, function ($hash, PasswordHasherInterface $password_hasher) use ($password) {
            if (empty($hash)) {
                $hash = $password_hasher->hash_password($password);
            }

            return $hash;
        });

        if (empty($hash)) {
            throw new \RuntimeException('Could not create a hash for the given password.');
        }

        return $hash;
    }

    // ...

    /**
     * {@inheritdoc}
     */
    public function is_password_valid($password, $hash)
    {
        return array_reduce($this->password_hashers, function ($check, PasswordHasherInterface $password_hasher) use ($password, $hash) {
            if (true !== $check) {
                $check = $password_hasher->is_password_valid($password, $hash);
            }

            return $check;
        }, false);
    }

    // ...
}
```

Above you can see these two methods which are `hash_password` and `is_password_valid`. Both methods are quite similar to one another. They rely on using the `array_reduce` function on the `password_hashers` array. Both anonymous functions passed to the `array_reduce` function are just a guard clause. The guard clause is there to determine if we want to return the current carry value or not. If we haven't, we get a new one from the current `password_hasher`. For the `hash_password` method, we want to stop trying to hash a password once we successfully hashed one. We can test for that using the [`empty`](https://www.php.net/manual/en/function.empty.php) function. If the `hash` carry value is empty, we know we haven't managed to hash the given `password` yet. For the `is_password_valid` method, the guard clause doesn't use the `empty` function. Instead, we only stop checking the password if `check` is [identical](https://www.php.net/manual/en/language.operators.comparison.php) to `true`. That's because we want every password hasher to have an opportunity to check the password. If we stopped when `check` was `false`, we might omit a password hasher that could validate the password. # How to use the chain

So that's it for the `PasswordHasherChain` class! We're going to wrap this up by looking at how to use it with our other password hashers. Here's how that looks: ```
if (!class_exists('PasswordHash')) {
    require_once ABSPATH . WPINC . '/class-phpass.php';
}

$password_hasher = new PasswordHasherChain([
    new NativePasswordHasher(),
    new WordPressPasswordHasher(new \PasswordHash(8, true)),
]);
```

The code above starts with a guard clause. We need it because WordPress doesn't always load the file containing the `PasswordHash` class. So we need to check to see if it's there first using the [`class_exists`](https://www.php.net/manual/en/function.class-exists.php) function. If the class doesn't exist, we require the `class-phpass.php` file. Once we've passed the guard clause, we initialize the `PasswordHasherChain` class. We pass it the array of password hashers which we initialize at the same time. The first one is `NativePasswordHasher` and the second one is the `WordPressPasswordHasher`. The order of the password hashers in the array is important here. The chain will stop once it finds a valid password hasher to perform an action. So we want to order them so that our preferred password hasher gets selected. For this scenario, we want the `WordPressPasswordHasher` to go last. We don't want it to hash new passwords using the WordPress algorithm. We only want it validate passwords that were already hashed using that algorithm. (This is why the `is_hash_valid` method of `WordPressPasswordHasher` class returns `false`.) # Seeing it in action

To see how the chain works in a plugin, I suggest looking at the [Passwords Evolved plugin](https://github.com/carlalexander/passwords-evolved/tree/v1.2.0) code. ([Reading code is a great way to learn](https://carlalexander.ca/read-more-code/) too!) You'll see how to replace the WordPress implementation with our own. There's also a third password hasher just for libsodium. If you're just interested in the code, you can [check out this gist](https://gist.github.com/carlalexander/c7c710c386119aeece20b27038a4bc75). *Photo Credit: [Vladyslav Cherkasenko](https://unsplash.com/@vl_cherkasenko)*