SECURITY: Replaced mt_rand with random_bytes

https://huntr.dev/bounties/2-phpservermon/phpservermon/
CWE-1241: Use of Predictable Algorithm in Random Number Generator
This commit is contained in:
Tim Zandbergen 2021-06-23 22:06:34 +02:00
parent bb10a5f3c6
commit 3daa804d5f
No known key found for this signature in database
GPG Key ID: 4D8268DC68E8339D
3 changed files with 26 additions and 23 deletions

View File

@ -30,7 +30,7 @@
/** /**
* Current PSM version * Current PSM version
*/ */
define('PSM_VERSION', '3.6.0.beta2'); define('PSM_VERSION', '3.6.0');
/** /**
* URL to check for updates. Will not be checked if turned off on config page. * URL to check for updates. Will not be checked if turned off on config page.

View File

@ -72,7 +72,7 @@ class User
protected $user_id; protected $user_id;
/** /**
*Current user preferences * Current user preferences
* @var array $user_preferences * @var array $user_preferences
*/ */
protected $user_preferences; protected $user_preferences;
@ -237,15 +237,15 @@ class User
} }
$dirauthconfig = psm_get_conf('dirauth_status'); $dirauthconfig = psm_get_conf('dirauth_status');
// LDAP auth enabled // LDAP auth enabled
if ($dirauthconfig === '1') { if ($dirauthconfig === '1') {
$ldaplibpath = realpath( $ldaplibpath = realpath(
PSM_PATH_SRC . '..' . DIRECTORY_SEPARATOR . PSM_PATH_SRC . '..' . DIRECTORY_SEPARATOR .
'vendor' . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR .
'viharm' . DIRECTORY_SEPARATOR . 'viharm' . DIRECTORY_SEPARATOR .
'psm-ldap-auth' . DIRECTORY_SEPARATOR . 'psm-ldap-auth' . DIRECTORY_SEPARATOR .
'psmldapauth.php' 'psmldapauth.php'
); );
// If the library is found // If the library is found
if ($ldaplibpath) { if ($ldaplibpath) {
@ -260,20 +260,20 @@ class User
// Authenticated // Authenticated
if ($ldapauthstatus === true) { if ($ldapauthstatus === true) {
// Remove password to prevent it from being saved in the DB. // Remove password to prevent it from being saved in the DB.
// Otherwise, user may still be authenticated if LDAP is disabled later. // Otherwise, user may still be authenticated if LDAP is disabled later.
$user_password = null; $user_password = null;
@fn_Debug('Authenticated', $user); @fn_Debug('Authenticated', $user);
} else { } else {
// using PHP 5.5's password_verify() function to check if the provided passwords // using PHP 5.5's password_verify() function to check if the provided passwords
// fits to the hash of that user's password // fits to the hash of that user's password
if (!isset($user->user_id)) { if (!isset($user->user_id)) {
password_verify($user_password, 'dummy_call_against_timing'); password_verify($user_password, 'dummy_call_against_timing');
return false; return false;
} elseif (!password_verify($user_password, $user->password)) { } elseif (!password_verify($user_password, $user->password)) {
return false; return false;
} }
} // not authenticated } // not authenticated
$this->setUserLoggedIn($user->user_id, true); $this->setUserLoggedIn($user->user_id, true);
@ -390,8 +390,8 @@ class User
} }
// generate timestamp (to see when exactly the user (or an attacker) requested the password reset mail) // generate timestamp (to see when exactly the user (or an attacker) requested the password reset mail)
$temporary_timestamp = time(); $temporary_timestamp = time();
// generate random hash for email password reset verification (40 char string) // generate random hash for email password reset verification (64 char string)
$user_password_reset_hash = sha1(uniqid(mt_rand(), true)); $user_password_reset_hash = hash('sha256', uniqid(random_bytes(64), true));
$query_update = $this->db_connection->prepare('UPDATE ' . $query_update = $this->db_connection->prepare('UPDATE ' .
PSM_DB_PREFIX . 'users SET password_reset_hash = :user_password_reset_hash, PSM_DB_PREFIX . 'users SET password_reset_hash = :user_password_reset_hash,

View File

@ -212,7 +212,7 @@ class Installer
`user_id` int(11) unsigned NOT NULL AUTO_INCREMENT, `user_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`user_name` varchar(64) NOT NULL COMMENT 'user''s name, unique', `user_name` varchar(64) NOT NULL COMMENT 'user''s name, unique',
`password` varchar(255) NOT NULL COMMENT 'user''s password in salted and hashed format', `password` varchar(255) NOT NULL COMMENT 'user''s password in salted and hashed format',
`password_reset_hash` char(40) DEFAULT NULL COMMENT 'user''s password reset code', `password_reset_hash` varchar(64) DEFAULT NULL COMMENT 'user''s password reset code',
`password_reset_timestamp` bigint(20) DEFAULT NULL COMMENT 'timestamp of the password reset request', `password_reset_timestamp` bigint(20) DEFAULT NULL COMMENT 'timestamp of the password reset request',
`rememberme_token` varchar(64) DEFAULT NULL COMMENT 'user''s remember-me cookie token', `rememberme_token` varchar(64) DEFAULT NULL COMMENT 'user''s remember-me cookie token',
`level` tinyint(2) unsigned NOT NULL DEFAULT '20', `level` tinyint(2) unsigned NOT NULL DEFAULT '20',
@ -230,7 +230,7 @@ class Installer
UNIQUE KEY `unique_username` (`user_name`) UNIQUE KEY `unique_username` (`user_name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;", ) ENGINE=MyISAM DEFAULT CHARSET=utf8;",
PSM_DB_PREFIX . PSM_DB_PREFIX .
'users_preferences' => "CREATE TABLE IF NOT EXISTS `" . PSM_DB_PREFIX . "users_preferences` ( 'users_preferences' => "CREATE TABLE IF NOT EXISTS `" . PSM_DB_PREFIX . "users_preferences` (
`user_id` int(11) unsigned NOT NULL, `user_id` int(11) unsigned NOT NULL,
`key` varchar(255) NOT NULL, `key` varchar(255) NOT NULL,
`value` varchar(255) NOT NULL, `value` varchar(255) NOT NULL,
@ -732,6 +732,7 @@ class Installer
/** /**
* Patch for v3.6.0 release * Patch for v3.6.0 release
* Added support for Discord and webhooks * Added support for Discord and webhooks
* Password_reset_hash varchar 40 -> 64 to allow for SHA256 hash
*/ */
protected function upgrade360() protected function upgrade360()
{ {
@ -758,6 +759,8 @@ class Installer
$queries[] = "INSERT INTO `" . PSM_DB_PREFIX . "users` ( $queries[] = "INSERT INTO `" . PSM_DB_PREFIX . "users` (
`user_name`, `level`, `name`, `email`) `user_name`, `level`, `name`, `email`)
VALUES ('__PUBLIC__', 30, 'Public page', 'publicpage@psm.psm')"; VALUES ('__PUBLIC__', 30, 'Public page', 'publicpage@psm.psm')";
$queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "users`
CHANGE `password_reset_hash` `password_reset_hash` VARCHAR( 64 ) DEFAULT NULL COMMENT 'user''s password reset code';";
$this->execSQL($queries); $this->execSQL($queries);
$this->log('Public page is now available. Added user \'__PUBLIC__\'. See documentation for more info.'); $this->log('Public page is now available. Added user \'__PUBLIC__\'. See documentation for more info.');