If a user were able to create a password with a leading null byte (unlikely, but syntactically valid), an attacker could trivially compromise the victim's account by attempting to sign in with a blank string.
$ php -v
PHP 8.3.2 (cli) (built: Jan 16 2024 13:46:41) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.3.2, Copyright (c) Zend Technologies
with Xdebug v3.3.0, Copyright (c) 2002-2023, by Derick Rethans
with Zend OPcache v8.3.2, Copyright (c), by Zend Technologies
<?php
declare(strict_types=1);
$pw = "\x00\x30";
$hash = password_hash($pw, PASSWORD_DEFAULT);
assert(password_verify(password: 'wrong', hash: $hash) === false, 'Incorect password should not verify');
assert(password_verify(password: '', hash: $hash) === false, 'Blank password should not verify');
assert(password_verify(password: $pw, hash: $hash) === true, 'Correct password should verify');
assert(password_verify(password: strrev($pw), hash: $hash) === false, 'Reversed correct password not should verify');
AssertionError: Blank password should not verify in .../pw_bug.php on line 9
Call Stack:
0.0002 496408 1. {main}() .../pw_bug.php:0
0.1998 496536 2. assert($assertion = FALSE, $description = 'Blank password should not verify') .../pw_bug.php:9
This could be catastrophic in the right circumstance, but the chance of that circumstance existing is extremely low. Typically a user would get blocked from setting a password containing (never mind starting with) binary data through input filtering and application-specific password rules. Similar rules are likely employed on the checking side, though usually less strict.
Summary
If a password stored with
password_hash
starts with a null byte (\x00
), testing a blank string as the password viapassword_verify
will incorrectly returntrue
.If a user were able to create a password with a leading null byte (unlikely, but syntactically valid), an attacker could trivially compromise the victim's account by attempting to sign in with a blank string.
Details
This appears to exist at least back to 8.1.0: https://3v4l.org/Z0pcl
PoC
$ cat pw_bug.php
$ php pw_bug.php
Impact
Medium?
This could be catastrophic in the right circumstance, but the chance of that circumstance existing is extremely low. Typically a user would get blocked from setting a password containing (never mind starting with) binary data through input filtering and application-specific password rules. Similar rules are likely employed on the checking side, though usually less strict.