diff --git a/install/sql/mysql.sql b/install/sql/mysql.sql index d98b8704b..e195ab4cb 100644 --- a/install/sql/mysql.sql +++ b/install/sql/mysql.sql @@ -1377,21 +1377,24 @@ CREATE TABLE IF NOT EXISTS `bb_users` -- Records of bb_users -- ---------------------------- INSERT INTO `bb_users` -VALUES ('-1', '0', 'Guest', 'd41d8cd98f00b204e9800998ecf8427e', '0', '0', '0', UNIX_TIMESTAMP(), '0', '0', '0', '', +VALUES ('-1', '0', 'Guest', '$2y$10$sfZSmqPio8mxxFQLRRXaFuVMkFKZARRz/RzqddfYByN3M53.CEe.O', '0', '0', + '0', UNIX_TIMESTAMP(), '0', '0', '0', '', 'ru', '0', '0', '0', '0', '0', '0', '0', '1900-01-01', '', '', '', '', '', '', '', '', '', '', '', '', '0', '0.00', 'default'), - ('-746', '0', 'bot', 'd41d8cd98f00b204e9800998ecf8427e', '0', '0', '0', UNIX_TIMESTAMP(), '0', '0', '0', '', + ('-746', '0', 'bot', '$2y$10$sfZSmqPio8mxxFQLRRXaFuVMkFKZARRz/RzqddfYByN3M53.CEe.O', '0', '0', + '0', UNIX_TIMESTAMP(), '0', '0', '0', '', 'ru', '0', '0', '0', '144', '0', '0', '0', '1900-01-01', 'bot@torrentpier.com', '', '', '', '', '', '', '', '', '', '', '', '0', '0.00', 'default'), - ('2', '1', 'admin', 'c3284d0f94606de1fd2af172aba15bf3', '0', '0', '0', UNIX_TIMESTAMP(), '0', '1', '1', '', 'ru', + ('2', '1', 'admin', '$2y$10$QeekUGqdfMO0yp7AT7la8OhgbiNBoJ627BO38MdS1h5kY7oX6UUKu', '0', '0', + '0', UNIX_TIMESTAMP(), '0', '1', '1', '', 'ru', '0', '0', '0', '304', '1', diff --git a/library/config.php b/library/config.php index 4e2261c1d..aa4575f7f 100644 --- a/library/config.php +++ b/library/config.php @@ -383,6 +383,11 @@ $bb_cfg['password_symbols'] = [ 'lowercase' => true // Строчные буквы ] ]; +$bb_cfg['password_hash_options'] = [ + // https://www.php.net/manual/ru/password.constants.php + 'algo' => PASSWORD_BCRYPT, + 'options' => [] +]; // Email $bb_cfg['emailer'] = [ diff --git a/library/includes/ucp/activate.php b/library/includes/ucp/activate.php index b3d103941..bd12a701c 100644 --- a/library/includes/ucp/activate.php +++ b/library/includes/ucp/activate.php @@ -26,7 +26,7 @@ if ($row = DB()->sql_fetchrow($result)) { if ($row['user_active'] && trim($row['user_actkey']) == '') { bb_die($lang['ALREADY_ACTIVATED']); } elseif ((trim($row['user_actkey']) == trim($_GET['act_key'])) && (trim($row['user_actkey']) != '')) { - $sql_update_pass = ($row['user_newpasswd'] != '') ? ", user_password = '" . md5(md5($row['user_newpasswd'])) . "', user_newpasswd = ''" : ''; + $sql_update_pass = ($row['user_newpasswd'] != '') ? ", user_password = '" . $user->password_hash($row['user_newpasswd']) . "', user_newpasswd = ''" : ''; $sql = "UPDATE " . BB_USERS . " SET user_active = 1, user_actkey = ''" . $sql_update_pass . " diff --git a/library/includes/ucp/register.php b/library/includes/ucp/register.php index 4296d63cb..ff6d383db 100644 --- a/library/includes/ucp/register.php +++ b/library/includes/ucp/register.php @@ -208,7 +208,7 @@ foreach ($profile_fields as $field => $can_edit) { $errors[] = $err; } - $db_data['user_password'] = md5(md5($new_pass)); + $db_data['user_password'] = $user->password_hash($new_pass); } if ($mode == 'register') { @@ -217,7 +217,7 @@ foreach ($profile_fields as $field => $can_edit) { } } else { if (!empty($cur_pass)) { - $cur_pass_valid = ($pr_data['user_password'] === md5(md5($cur_pass))); + $cur_pass_valid = $user->checkPassword($cur_pass, $pr_data); } if (!empty($new_pass) && !$cur_pass_valid) { $errors[] = $lang['CHOOSE_PASS_FAILED']; diff --git a/src/Legacy/Common/User.php b/src/Legacy/Common/User.php index 2df3235c8..f2314a974 100644 --- a/src/Legacy/Common/User.php +++ b/src/Legacy/Common/User.php @@ -365,35 +365,38 @@ class User /** * Login * - * @param $args + * @param array $args * @param bool $mod_admin_login * * @return array */ - public function login($args, $mod_admin_login = false) + public function login(array $args, bool $mod_admin_login = false): array { $username = !empty($args['login_username']) ? clean_username($args['login_username']) : ''; $password = !empty($args['login_password']) ? $args['login_password'] : ''; if ($username && $password) { $username_sql = str_replace("\\'", "''", $username); - $password_sql = md5(md5($password)); $sql = " SELECT * FROM " . BB_USERS . " WHERE username = '$username_sql' - AND user_password = '$password_sql' AND user_active = 1 AND user_id != " . GUEST_UID . " LIMIT 1 "; if ($userdata = DB()->fetch_row($sql)) { - if (!$userdata['username'] || !$userdata['user_password'] || $userdata['user_id'] == GUEST_UID || md5(md5($password)) !== $userdata['user_password'] || !$userdata['user_active']) { + if (!$userdata['username'] || !$userdata['user_password'] || ($userdata['user_id'] == GUEST_UID) || !$userdata['user_active']) { trigger_error('invalid userdata', E_USER_ERROR); } + // Check password + if (!$this->checkPassword($password, $userdata)) { + return []; + } + // Start mod/admin session if ($mod_admin_login) { DB()->query(" @@ -756,4 +759,47 @@ class User return array_flip(explode(',', $excluded)); } } + + /** + * Check entered password + * + * @param string $enteredPassword + * @param array $userdata + * @return bool + */ + public function checkPassword(string $enteredPassword, array $userdata): bool + { + global $bb_cfg; + + if (password_verify($enteredPassword, $userdata['user_password'])) { + if (password_needs_rehash($userdata['user_password'], $bb_cfg['password_hash_options']['algo'], $bb_cfg['password_hash_options']['options'])) { + // Update password_hash + DB()->query("UPDATE " . BB_USERS . " SET user_password = '" . $this->password_hash($enteredPassword) . "' WHERE user_id = '" . $userdata['user_id'] . "' AND user_password = '" . $userdata['user_password'] . "' LIMIT 1"); + } + + return true; + } else { + if (md5(md5($enteredPassword)) === $userdata['user_password']) { + // Update old md5 password + DB()->query("UPDATE " . BB_USERS . " SET user_password = '" . $this->password_hash($enteredPassword) . "' WHERE user_id = '" . $userdata['user_id'] . "' AND user_password = '" . $userdata['user_password'] . "' LIMIT 1"); + + return true; + } + } + + return false; + } + + /** + * Create password_hash + * + * @param string $enteredPassword + * @return false|string|null + */ + public function password_hash(string $enteredPassword) + { + global $bb_cfg; + + return password_hash($enteredPassword, $bb_cfg['password_hash_options']['algo'], $bb_cfg['password_hash_options']['options']); + } }