CVE-2021-4240 (PHP, published 2022-11-15T23:15Z)
Description: value: A vulnerability, which was classified as problematic, was found in phpservermon. This affects the function generatePasswordResetToken of the file src/psm/Service/User.php. The manipulation leads to use of predictable algorithm in random number generator. The exploit has been disclosed to the public and may be used. The name of the patch is 3daa804d5f56c55b3ae13bfac368bb84ec632193. It is recommended to apply a patch to fix this issue. The identifier VDB-213717 was assigned to this vulnerability.
Severity: nan (CVSS v3 base score: 5.3)
Weakness: CWE-330 \u2014 Use of Insufficiently Random Values
The product uses insufficiently random numbers or values in a security context that depends on unpredictable numbers.
Repository: https://github.com/phpservermon/phpservermon
Files changed:
src/includes/psmconfig.inc.php
src/psm/Service/User.php
src/psm/Util/Install/Installer.php
Commit message: SECURITY: Replaced mt_rand with random_bytes

https://huntr.dev/bounties/2-phpservermon/phpservermon/
CWE-1241: Use of Predictable Algorithm in Random Number Generator


Vulnerable code:
define('PSM_VERSION', '3.6.0.beta2');
     *Current user preferences
        
                'vendor' . DIRECTORY_SEPARATOR .
                'viharm' . DIRECTORY_SEPARATOR .
                'psm-ldap-auth' . DIRECTORY_SEPARATOR .
                'psmldapauth.php'
          // Remove password to prevent it from being saved in the DB.
          // Otherwise, user may still be authenticated if LDAP is disabled later.
          $user_password = null;
          @fn_Debug('Authenticated', $user);
          // using PHP 5.5's password_verify() function to check if the provided passwords
          // fits to the hash of that user's password
          if (!isset($user->user_id)) {
              password_verify($user_password, 'dummy_call_against_timing');
              return false;
          } elseif (!password_verify($user_password, $user->password)) {
              return false;
          }
        // generate random hash for email password reset verification (40 char string)
        $user_password_reset_hash = sha1(uniqid(mt_rand(), true));
                `password_reset_hash` char(40) DEFAULT NULL COMMENT 'user''s password reset code',
            'users_preferences' => "CREATE TABLE IF NOT EXISTS `" . PSM_DB_PREFIX . "users_preferences` (

Fixed code:
define('PSM_VERSION', '3.6.0');
     * Current user preferences

                    'vendor' . DIRECTORY_SEPARATOR .
                    'viharm' . DIRECTORY_SEPARATOR .
                    'psm-ldap-auth' . DIRECTORY_SEPARATOR .
                    'psmldapauth.php'
            // Remove password to prevent it from being saved in the DB.
            // Otherwise, user may still be authenticated if LDAP is disabled later.
            $user_password = null;
            @fn_Debug('Authenticated', $user);
            // using PHP 5.5's password_verify() function to check if the provided passwords
            // fits to the hash of that user's password
            if (!isset($user->user_id)) {
                password_verify($user_password, 'dummy_call_against_timing');
                return false;
            } elseif (!password_verify($user_password, $user->password)) {
                return false;
            }
        // generate random hash for email password reset verification (64 char string)
        $user_password_reset_hash = hash('sha256', uniqid(random_bytes(64), true));
                `password_reset_hash` varchar(64) DEFAULT NULL COMMENT 'user''s password reset code',
                'users_preferences' => "CREATE TABLE IF NOT EXISTS `" . PSM_DB_PREFIX . "users_preferences` (
     * Password_reset_hash varchar 40 -> 64 to allow for SHA256 hash
        $queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "users`
            CHANGE `password_reset_hash` `password_reset_hash`  VARCHAR( 64 ) DEFAULT NULL COMMENT 'user''s password reset code';";