From https://www.php.net/manual/en/function.hash-equals: > Both arguments must be of the same length to be compared successfully. When arguments of differing length are supplied, false is returned immediately and the length of the known string may be leaked in case of a timing attack. > It is important to provide the user-supplied string as the second parameter, rather than the first. It is used in the wrong way from `verify` static function, defeating `hash_equals`'s goal of preventing timing attacks. ```PHP private static function verify($msg, $signature, $key, $alg) { ... $hash = \hash_hmac($algorithm, $msg, $key, true); return self::constantTimeEquals($signature, $hash); ``` ```PHP public static function constantTimeEquals($left, $right) { if (\function_exists('hash_equals')) { return \hash_equals($left, $right); } ``` https://github.com/firebase/php-jwt/blob/83b609028194aa042ea33b5af2d41a7427de80e6/src/JWT.php#L297