Users: transparently upgrade passwords to Argon2
[?]
Apr 15, 2021, 2:55 PM
56Q5PJPG6ASJV5OFPJZYBSFGDL3G55CDQE3JBKK7KTEBGXSAXAXACDependencies
- [2]
2G37UFZFflake: add TestPostgreSQL for per-test DBs - [3]
ASPD4MDNPasswords: check in constant time - [4]
S66BOMVU* Added authentication. - [5]
SYLVCTT6Start api cleanup with the User model - [*]
RWNXH3H2lastModified -> lastModifiedDate
Change contents
- edit in flake.nix at line 70
};};CryptArgon2 = final.perlPackages.buildPerlModule {pname = "Crypt-Argon2";version = "0.010";src = final.fetchurl {url = "mirror://cpan/authors/id/L/LE/LEONT/Crypt-Argon2-0.010.tar.gz";sha256 = "3ea1c006f10ef66fd417e502a569df15c4cc1c776b084e35639751c41ce6671a";};nativeBuildInputs = [ pkgs.ld-is-cc-hook ];meta = {description = "Perl interface to the Argon2 key derivation functions";license = final.lib.licenses.cc0; - edit in flake.nix at line 87
CryptPassphrase = final.buildPerlPackage {pname = "Crypt-Passphrase";version = "0.003";src = final.fetchurl {url = "mirror://cpan/authors/id/L/LE/LEONT/Crypt-Passphrase-0.003.tar.gz";sha256 = "685aa090f8179a86d6896212ccf8ccfde7a79cce857199bb14e2277a10d240ad";};meta = {description = "A module for managing passwords in a cryptographically agile manner";license = with final.lib.licenses; [ artistic1 gpl1Plus ];};};CryptPassphraseArgon2 = final.buildPerlPackage {pname = "Crypt-Passphrase-Argon2";version = "0.002";src = final.fetchurl {url = "mirror://cpan/authors/id/L/LE/LEONT/Crypt-Passphrase-Argon2-0.002.tar.gz";sha256 = "3906ff81697d13804ee21bd5ab78ffb1c4408b4822ce020e92ecf4737ba1f3a8";};propagatedBuildInputs = with final.perlPackages; [ CryptArgon2 CryptPassphrase ];meta = {description = "An Argon2 encoder for Crypt::Passphrase";license = with final.lib.licenses; [ artistic1 gpl1Plus ];};}; - edit in flake.nix at line 311[7.1996][7.1996]
CryptPassphraseCryptPassphraseArgon2 - edit in src/lib/Hydra/Schema/Users.pm at line 198
use Crypt::Passphrase; - replacement in src/lib/Hydra/Schema/Users.pm at line 220
return String::Compare::ConstantTime::equals($self->password, sha1_hex($password));my $authenticator = Crypt::Passphrase->new(encoder => 'Argon2',validators => [(sub {my ($password, $hash) = @_;return String::Compare::ConstantTime::equals($hash, sha1_hex($password));})],);if ($authenticator->verify_password($password, $self->password)) {if ($authenticator->needs_rehash($self->password)) {$self->update({"password" => $authenticator->hash_password($password),});}return 1;} else {return 0;} - replacement in t/Schema/Users.t at line 14
# Catalyst's default password checking is not constant time. To improve# the security of the system, we replaced the check password routine.# Verify comparing correct and incorrect passwords work.# Hydra used to store passwords, by default, as plain unsalted sha1 hashes.# We now upgrade these badly stored passwords with much stronger algorithms# when the user logs in. Implementing this meant reimplementing our password# checking ourselves, so also ensure that basic password checking works.## This test:## 1. creates a user with the legacy password# 2. validates that the wrong password is not considered valid# 3. validates that the correct password is valid# 4. checks that the checking of the correct password transparently upgraded# the password's storage to a more secure algorithm. - replacement in t/Schema/Users.t at line 27
# Starting the user with a sha1 password# Starting the user with an unsalted sha1 password - edit in t/Schema/Users.t at line 36
is($user->password, "8843d7f92416211de9ebb963ff4ce28125932878", "The unsalted sha1 is in the database."); - edit in t/Schema/Users.t at line 39
isnt($user->password, "8843d7f92416211de9ebb963ff4ce28125932878", "The user has had their password rehashed.");ok($user->check_password("foobar"), "Checking the password, foobar, is still right");