Skip to content

password_verify can erroneously return true, opening ATO risk

Low
bukka published GHSA-h746-cjrr-wfmr Apr 11, 2024

Package

No package listed

Affected versions

< 8.1.28
< 8.2.18
< 8.3.5

Patched versions

8.1.28
8.2.18
8.3.6

Description

Summary

If a password stored with password_hash starts with a null byte (\x00), testing a blank string as the password via password_verify will incorrectly return true.

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

$ 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

This appears to exist at least back to 8.1.0: https://3v4l.org/Z0pcl

PoC

$ cat pw_bug.php

<?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');

$ php pw_bug.php

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

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.

Severity

Low

CVE ID

CVE-2024-3096

Weaknesses

Credits