php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Sec Bug #70743 password_hash() and crypt() should not use php_rand() to generate salts
Submitted: 2015-10-19 20:10 UTC Modified: 2015-12-31 23:41 UTC
Votes:2
Avg. Score:5.0 ± 0.0
Reproduced:0 of 0 (0.0%)
From: fsb at thefsb dot org Assigned: stas (profile)
Status: Closed Package: hash related
PHP Version: 7.0.0RC5 OS: any
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: fsb at thefsb dot org
New email:
PHP Version: OS:

 

 [2015-10-19 20:10 UTC] fsb at thefsb dot org
Description:
------------
/ext/standard/password.c uses php_rand() to generate a password salt for password_hash() if attempts to read random bytes from the OS's CSPRNG fail.
https://github.com/php/php-src/blob/php-7.0.0RC5/ext/standard/password.c#L153-L157

php_rand() is a simpel LCG and unsuitable for salt generation. All previous and future outputs are known from either the seed or from any given output. PHP scripts can seed it, which is unsafe. If they don't, PHP seeds it from a function of its PID and time(0), which is also unsafe.

The salt generator for crypt() also resorts to php_rand().

PHP 7.0 introduces random_bytes(), which throws \Exception if it cannot read from the OS's CSPRNG. password_hash() and crypt() should do the same.

Test script:
---------------
<?php
// On a Linux/BSD-like system with access to /dev/random disabled
$seed = 1073741824; // Choose any value you like
srand($seed);
echo password_hash('password', PASSWORD_DEFAULT) . "\n";
srand($seed);
echo password_hash('password', PASSWORD_DEFAULT) . "\n";
srand($seed);
echo password_hash('password', PASSWORD_DEFAULT) . "\n";
srand($seed);
echo password_hash('password', PASSWORD_DEFAULT) . "\n";


Expected result:
----------------
Any function that purports to salt passwords for hashing, such as password_hash(), should not leave it self open to collisions.

Actual result:
--------------
$2y$10$N34AYO6UZV0eADdJpnoyr.Z/ha44pJhmgT/KN24Mf7prVMjEbiaR.
$2y$10$N34AYO6UZV0AAAAAAAAAA./YVu4n4IudpH8uXavEoL1O6YlyNFhBy
$2y$10$N34AYO6UZV0eADdJpnoyr.Z/ha44pJhmgT/KN24Mf7prVMjEbiaR.
$2y$10$N34AYO6UZV0AAAAAAAAAA./YVu4n4IudpH8uXavEoL1O6YlyNFhBy


Patches

Add a Patch

Pull Requests

Pull requests:

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-10-19 20:11 UTC] fsb at thefsb dot org
https://github.com/php/php-src/pull/1585
 [2015-12-31 23:41 UTC] stas@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: stas
 [2015-12-31 23:41 UTC] stas@php.net
The fix for this bug has been committed.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.

 For Windows:

http://windows.php.net/snapshots/
 
Thank you for the report, and for helping us make PHP better.

I understand this is fixed now.
 
PHP Copyright © 2001-2021 The PHP Group
All rights reserved.
Last updated: Fri Sep 17 07:03:36 2021 UTC