From 031351861c5d74588a3188caf2f5039c33dae44d Mon Sep 17 00:00:00 2001
From: Pawel
Date: Wed, 14 Jan 2026 12:48:01 +0000
Subject: [PATCH 1/2] Updated match_password/encrypt_password methods to use
Crypt::Passphrase for validation/encryption
---
.../Plugin/Auth/Extensible/Role/Provider.pm | 65 ++++++++++---------
1 file changed, 34 insertions(+), 31 deletions(-)
diff --git a/lib/Dancer2/Plugin/Auth/Extensible/Role/Provider.pm b/lib/Dancer2/Plugin/Auth/Extensible/Role/Provider.pm
index 4c77ffb..9876175 100644
--- a/lib/Dancer2/Plugin/Auth/Extensible/Role/Provider.pm
+++ b/lib/Dancer2/Plugin/Auth/Extensible/Role/Provider.pm
@@ -1,10 +1,12 @@
package Dancer2::Plugin::Auth::Extensible::Role::Provider;
use Crypt::SaltedHash;
+use Crypt::Passphrase;
+use Crypt::Passphrase::Argon2;
use Moo::Role;
requires qw(authenticate_user);
-our $VERSION = '0.710';
+our $VERSION = '0.712';
=head1 NAME
@@ -49,13 +51,15 @@ has disable_roles => (
The encryption_algorithm used by L.
-Defaults to 'SHA-512';
+Defaults to 'Argon2';
=cut
has encryption_algorithm => (
is => 'ro',
- default => 'SHA-512',
+ default => sub {
+ Crypt::Passphrase::Argon2->new;
+ },
);
=head1 METHODS
@@ -71,35 +75,34 @@ sub match_password {
# If $correct is undefined, then do not attempt a match, otherwise an
# uninnitialized warning will be thrown. If stack trace warnings are
- # enabled and if the user is using a password that is correct for another
- # system, then the user's attempted password may be written in logs. This
- # is certainly an edge-case, but it has happened :)
- # Also as a safety check, do not allow blank passwords, in case a user has
- # not set a password yet and a blank password is submitted for
- # authentication.
+ # enabled, the user's attempted password may be written in logs.
+ # Also as a safety check, do not allow blank passwords.
$correct or return;
-
- # TODO: perhaps we should accept a configuration option to state whether
- # passwords are crypted or not, rather than guessing by looking for the
- # {...} tag at the start.
- # I wanted to let it try straightforward comparison first, then try
- # Crypt::SaltedHash->validate, but that has a weakness: if a list of hashed
- # passwords got leaked, you could use the hashed password *as it is* to log
- # in, rather than cracking it first. That's obviously Not Fucking Good.
- # TODO: think about this more. This shit is important. I'm thinking a
- # config option to indicate whether passwords are crypted - yes, no, auto
+
+ # TODO: A config option to indicate whether passwords are crypted - yes, no, auto
# (where auto would do the current guesswork, and yes/no would just do as
# told.)
+
if ( $correct =~ /^{.+}/ ) {
-
- # Looks like a crypted password starting with the scheme, so try to
- # validate it with Crypt::SaltedHash:
- return Crypt::SaltedHash->validate( $correct, $given );
- }
- else {
- # Straightforward comparison, then:
- return $given eq $correct;
+ # Looks like a legacy crypted password starting with the scheme, so try to
+ # validate it with Crypt::SaltedHash.
+ return {
+ valid => Crypt::SaltedHash->validate( $correct, $given ),
+ legacy => 1,
+ };
}
+
+ # Not validated by legacy validator, so now check with Crypt::Passphrase.
+ # If unsuccessful, valid will return false.
+
+ my $passphrase = Crypt::Passphrase->new(
+ encoder => $self->encryption_algorithm,
+ );
+
+ return {
+ valid => $passphrase->verify_password( $given, $correct ),
+ legacy => 0,
+ };
}
=head2 encrypt_password $password
@@ -111,10 +114,10 @@ and returns the encrypted password.
sub encrypt_password {
my ( $self, $password ) = @_;
- my $crypt =
- Crypt::SaltedHash->new( algorithm => $self->encryption_algorithm );
- $crypt->add($password);
- $crypt->generate;
+ my $passphrase = Crypt::Passphrase->new(
+ encoder => $self->encryption_algorithm,
+ );
+ return $passphrase->hash_password($password);
}
=head1 METHODS IMPLEMENTED BY PROVIDER
From 7f9d2f59c61d2bd536b1982678a7cd0fae2ba336 Mon Sep 17 00:00:00 2001
From: Pawel
Date: Tue, 14 Apr 2026 10:24:01 +0100
Subject: [PATCH 2/2] Added stricter regex and return values upon failure
---
lib/Dancer2/Plugin/Auth/Extensible/Role/Provider.pm | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/lib/Dancer2/Plugin/Auth/Extensible/Role/Provider.pm b/lib/Dancer2/Plugin/Auth/Extensible/Role/Provider.pm
index 9876175..bd51f80 100644
--- a/lib/Dancer2/Plugin/Auth/Extensible/Role/Provider.pm
+++ b/lib/Dancer2/Plugin/Auth/Extensible/Role/Provider.pm
@@ -77,13 +77,15 @@ sub match_password {
# uninnitialized warning will be thrown. If stack trace warnings are
# enabled, the user's attempted password may be written in logs.
# Also as a safety check, do not allow blank passwords.
- $correct or return;
+ return { valid => 0, legacy => undef }
+ unless defined $correct && length $correct;
# TODO: A config option to indicate whether passwords are crypted - yes, no, auto
# (where auto would do the current guesswork, and yes/no would just do as
# told.)
- if ( $correct =~ /^{.+}/ ) {
+ if ( $correct =~ /^\{\w+\}/ )
+ {
# Looks like a legacy crypted password starting with the scheme, so try to
# validate it with Crypt::SaltedHash.
return {