Hash editor passwords with Argon2id and upgrade old hashes.
Old hashes are replaced at login. Widen the column before deploying: ALTER TABLE editors MODIFY password VARCHAR(255) NOT NULL;
This commit is contained in:
@@ -132,3 +132,44 @@ function login_editor($username) {
|
||||
unset($_SESSION['csrf_token']);
|
||||
$_SESSION['editor'] = $username;
|
||||
}
|
||||
|
||||
/*
|
||||
* Password hashing: Argon2id where PHP was built with it, otherwise
|
||||
* bcrypt. Argon2id hashes are about 100 characters long, so the
|
||||
* editors.password column must hold at least that (VARCHAR(255) is best).
|
||||
*/
|
||||
function password_algorithm() {
|
||||
return defined('PASSWORD_ARGON2ID') ? PASSWORD_ARGON2ID : PASSWORD_BCRYPT;
|
||||
}
|
||||
|
||||
/*
|
||||
* Store $hash as the password of $username, and return TRUE if the database kept
|
||||
* the whole hash. The database must be open.
|
||||
*/
|
||||
function store_password_hash($username, $hash) {
|
||||
global $db;
|
||||
$db->execute_query("UPDATE editors SET password = ? WHERE username = ?", array($hash, $username));
|
||||
return password_hash_is_stored($username, $hash);
|
||||
}
|
||||
|
||||
// TRUE if the database holds exactly $hash for $username
|
||||
function password_hash_is_stored($username, $hash) {
|
||||
global $db;
|
||||
$check = $db->execute_query("SELECT password FROM editors WHERE username = ?", array($username));
|
||||
$row = $check ? $check->fetch_assoc() : NULL;
|
||||
return $row && $row['password'] === $hash;
|
||||
}
|
||||
|
||||
/*
|
||||
* After a successful login, move an old hash (MD5-crypt, bcrypt) to the
|
||||
* current algorithm. If the column is too short and MySQL cut the new
|
||||
* hash, put the old one back so that the editor can still log in.
|
||||
*/
|
||||
function rehash_password($username, $password, $stored_hash) {
|
||||
if (!password_needs_rehash($stored_hash, password_algorithm()))
|
||||
return;
|
||||
if (!store_password_hash($username, password_hash($password, password_algorithm()))) {
|
||||
store_password_hash($username, $stored_hash);
|
||||
error_log("xxx: could not store a new password hash for $username; widen editors.password");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user