Users: add a validation step which lets the user's password be a Argon2 hashed sha1 hash.

OWASP suggests expiring all passwords and requiring users to update their password.
However, we don't have a way to do this. They suggest this mechanism
as a good alternative:
https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#upgrading-legacy-hashes
This commit is contained in:
Graham Christensen 2021-04-16 09:58:46 -04:00
parent fa924ea697
commit d10d8964f2
2 changed files with 17 additions and 0 deletions

View file

@ -238,6 +238,12 @@ sub check_password {
$self->setPassword($password); $self->setPassword($password);
} }
return 1;
} elsif ($authenticator->verify_password(sha1_hex($password), $self->password)) {
# The user's database record has their old password as sha1, re-hashed as Argon2.
# Store their password hashed only with Argon2.
$self->setPassword($password);
return 1; return 1;
} else { } else {
return 0; return 0;

View file

@ -39,4 +39,15 @@ ok($user->check_password("foobar"), "Checking the password, foobar, is right");
isnt($user->password, "8843d7f92416211de9ebb963ff4ce28125932878", "The user has had their password rehashed."); isnt($user->password, "8843d7f92416211de9ebb963ff4ce28125932878", "The user has had their password rehashed.");
ok($user->check_password("foobar"), "Checking the password, foobar, is still right"); ok($user->check_password("foobar"), "Checking the password, foobar, is still right");
# All sha1 passwords will be upgraded when `hydra-init` is run, by passing the sha1 through
# Argon2. Verify a rehashed sha1 validates too. This removes very weak password hashes
# from the database without requiring users to log in.
subtest "Hashing their sha1 as Argon2 still lets them log in with their password" => sub {
$user->setPassword("8843d7f92416211de9ebb963ff4ce28125932878"); # SHA1 of "foobar"
my $hashedHashPassword = $user->password;
isnt($user->password, "8843d7f92416211de9ebb963ff4ce28125932878", "The user has had their password's hash rehashed.");
ok($user->check_password("foobar"), "Checking the password, foobar, is still right");
isnt($user->password, $hashedHashPassword, "The user's hashed hash was replaced with just Argon2.");
};
done_testing; done_testing;