Session creation mixup when supplying an existing _session_id
Concerned version
Version: 2.0.7
Platform: (Nginx/Apache/Node.js)
Summary
I have encountered the following bug:
- Configure 2 second factors that use a form (ext and mail)
- set tokenUseGlobalStorage=1
- use two nodes with no session affinity
- store sessions in DB
- Second factor verification will randomly fail with "authentication timeout"
Logs
The bug happens here, in ::2F::Engine::Default.pm
# New token
$token = $self->ott->createToken($session);
When using useTokenGlobalStorage
, the new token isn't so new!
[debug] Try to get TOKEN session 7ad37b7fc1c40a70c943f89c767afb77f1c7a4c6734cd4295e0691ffb05af634
[debug] Get session 7ad37b7fc1c40a70c943f89c767afb77f1c7a4c6734cd4295e0691ffb05af634 from Portal::Main::Run
[debug] Return TOKEN session 7ad37b7fc1c40a70c943f89c767afb77f1c7a4c6734cd4295e0691ffb05af634
### At this point, 7ad37... no longer exists in the DB, but still exists in cache ###
### createToken is called here, but reuses the same ID!
[debug] Try to get a new TOKEN session
[debug] Return TOKEN session 7ad37b7fc1c40a70c943f89c767afb77f1c7a4c6734cd4295e0691ffb05af634
[debug] Token 7ad37b7fc1c40a70c943f89c767afb77f1c7a4c6734cd4295e0691ffb05af634 created
[debug] Generated two-factor code: 228995
[debug] Try to get TOKEN session 7ad37b7fc1c40a70c943f89c767afb77f1c7a4c6734cd4295e0691ffb05af634
[debug] Get session 7ad37b7fc1c40a70c943f89c767afb77f1c7a4c6734cd4295e0691ffb05af634 from Portal::Main::Run
[debug] Return TOKEN session 7ad37b7fc1c40a70c943f89c767afb77f1c7a4c6734cd4295e0691ffb05af634
That's because we call getApacheSession with an $info array that contains a previous _session_id.
The code ends up creating a new session, but then immediately forgetting about it and trying to write in the old, deleted one.
Possible fixes
My proposed fix is to ignore existing _session_id in info
when creating a new session:
diff --git a/lemonldap-ng-common/lib/Lemonldap/NG/Common/Session.pm b/lemonldap-ng-common/lib/Lemonldap/NG/Common/Session.pm
index c83435be0..ca9081b97 100644
--- a/lemonldap-ng-common/lib/Lemonldap/NG/Common/Session.pm
+++ b/lemonldap-ng-common/lib/Lemonldap/NG/Common/Session.pm
@@ -131,6 +131,7 @@ sub BUILD {
if ( $self->{info} ) {
foreach ( keys %{ $self->{info} } ) {
+ next if ($_ eq "_session_id");
if ( defined $self->{info}->{$_} ) {
$data->{$_} = $self->{info}->{$_};
}