Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[PasswordHasher] Make bcrypt nul byte hash test tolerant to PHP related failures #54858

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -98,16 +98,44 @@ public function testBcryptWithLongPassword()
$this->assertTrue($hasher->verify($hasher->hash($plainPassword), $plainPassword));
}

public function testBcryptWithNulByte()
/**
* @requires PHP < 8.4
*/
public function testBcryptWithNulByteWithNativePasswordHash()
{
$hasher = new NativePasswordHasher(null, null, 4, \PASSWORD_BCRYPT);
$plainPassword = "a\0b";

if (\PHP_VERSION_ID < 80218 || \PHP_VERSION_ID >= 80300 && \PHP_VERSION_ID < 80305) {
// password_hash() does not accept passwords containing NUL bytes since PHP 8.2.18 and 8.3.5
$this->assertFalse($hasher->verify(password_hash($plainPassword, \PASSWORD_BCRYPT, ['cost' => 4]), $plainPassword));
try {
$hash = password_hash($plainPassword, \PASSWORD_BCRYPT, ['cost' => 4]);
} catch (\Throwable $throwable) {
// we skip the test in case the current PHP version does not support NUL bytes in passwords
// with bcrypt
//
// @see https://github.com/php/php-src/commit/11f2568767660ffe92fbc6799800e01203aad73a
if (str_contains($throwable->getMessage(), 'Bcrypt password must not contain null character')) {
$this->markTestSkipped('password_hash() does not accept passwords containing NUL bytes.');
}

throw $throwable;
}

if (null === $hash) {
// we also skip the test in case password_hash() returns null as
// implemented in security patches backports
//
// @see https://github.com/shivammathur/php-src-backports/commit/d22d9ebb29dce86edd622205dd1196a2796c08c7
$this->markTestSkipped('password_hash() does not accept passwords containing NUL bytes.');
}

$this->assertTrue($hasher->verify($hash, $plainPassword));
}

public function testPasswordNulByteGracefullyHandled()
{
$hasher = new NativePasswordHasher(null, null, 4, \PASSWORD_BCRYPT);
$plainPassword = "a\0b";

$this->assertTrue($hasher->verify($hasher->hash($plainPassword), $plainPassword));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,17 +73,45 @@ public function testBcryptWithLongPassword()
$this->assertTrue($hasher->verify((new NativePasswordHasher(null, null, 4, \PASSWORD_BCRYPT))->hash($plainPassword), $plainPassword));
}

public function testBcryptWithNulByte()
/**
* @requires PHP < 8.4
*/
public function testBcryptWithNulByteWithNativePasswordHash()
{
$hasher = new SodiumPasswordHasher(null, null);
$plainPassword = "a\0b";

if (\PHP_VERSION_ID < 80218 || \PHP_VERSION_ID >= 80300 && \PHP_VERSION_ID < 80305) {
// password_hash() does not accept passwords containing NUL bytes since PHP 8.2.18 and 8.3.5
$this->assertFalse($hasher->verify(password_hash($plainPassword, \PASSWORD_BCRYPT, ['cost' => 4]), $plainPassword));
try {
$hash = password_hash($plainPassword, \PASSWORD_BCRYPT, ['cost' => 4]);
} catch (\Throwable $throwable) {
// we skip the test in case the current PHP version does not support NUL bytes in passwords
// with bcrypt
//
// @see https://github.com/php/php-src/commit/11f2568767660ffe92fbc6799800e01203aad73a
if (str_contains($throwable->getMessage(), 'Bcrypt password must not contain null character')) {
$this->markTestSkipped('password_hash() does not accept passwords containing NUL bytes.');
}

throw $throwable;
}

$this->assertTrue($hasher->verify((new NativePasswordHasher(null, null, 4, \PASSWORD_BCRYPT))->hash($plainPassword), $plainPassword));
if (null === $hash) {
// we also skip the test in case password_hash() returns null as
// implemented in security patches backports
//
// @see https://github.com/shivammathur/php-src-backports/commit/d22d9ebb29dce86edd622205dd1196a2796c08c7
$this->markTestSkipped('password_hash() does not accept passwords containing NUL bytes.');
}

$this->assertTrue($hasher->verify($hash, $plainPassword));
}

public function testPasswordNulByteGracefullyHandled()
{
$hasher = new SodiumPasswordHasher(null, null);
$plainPassword = "a\0b";

$this->assertTrue($hasher->verify($hasher->hash($plainPassword), $plainPassword));
}

public function testUserProvidedSaltIsNotUsed()
Expand Down