From 4b556a6840a02bb4e748a7819226c27a00adf76f Mon Sep 17 00:00:00 2001 From: Matt Porritt Date: Sat, 26 Aug 2023 17:26:41 +1000 Subject: [PATCH] MDL-79134 Backup: Deprecate MD5 for included user passwords Prevent backups containing legacy MD5 hashed user passwords from being added back into the database. Hashes are converted to random SHA512 hashed passwords upon restore for these backups. --- backup/upgrade.txt | 2 ++ backup/util/dbops/restore_dbops.class.php | 15 +++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/backup/upgrade.txt b/backup/upgrade.txt index d57f2465a5f..6fda6cb208a 100644 --- a/backup/upgrade.txt +++ b/backup/upgrade.txt @@ -5,6 +5,8 @@ information provided here is intended especially for developers. * The function get_async_backup_links_backup has a new param of $backupid and is part of a fix to async backups (See MDL-69983). +* During restore the function create_included_users has been updated to convert backups containing + legacy MD5 hashed passwords to the new password hashing scheme (See MDL-79134). === 4.1 === diff --git a/backup/util/dbops/restore_dbops.class.php b/backup/util/dbops/restore_dbops.class.php index 07856b57562..0633fd8567c 100644 --- a/backup/util/dbops/restore_dbops.class.php +++ b/backup/util/dbops/restore_dbops.class.php @@ -1253,6 +1253,10 @@ abstract class restore_dbops { } else if ($userauth->isinternal and $userauth->canresetpwd) { $user->password = 'restored'; } + } else if (self::password_should_be_discarded($user->password)) { + // Password is not empty and it is MD5 hashed. Generate a new random password for the user. + // We don't want MD5 hashes in the database and users won't be able to log in with the associated password anyway. + $user->password = hash_internal_user_password(base64_encode(random_bytes(24))); } // Creating new user, we must reset the policyagreed always @@ -1904,6 +1908,17 @@ abstract class restore_dbops { public static function delete_course_content($courseid, array $options = null) { return remove_course_contents($courseid, false, $options); } + + /** + * Checks if password stored in backup is a MD5 hash. + * Returns true if it is, false otherwise. + * + * @param string $password The password to check. + * @return bool + */ + private static function password_should_be_discarded(#[\SensitiveParameter] string $password): bool { + return (bool) preg_match('/^[0-9a-f]{32}$/', $password); + } } /*