From b14ee605eb9a2b603c36ada8dbdff16431ef8451 Mon Sep 17 00:00:00 2001
From: Jared Hancock <jared.hancock@cleco.com>
Date: Tue, 12 Sep 2017 15:55:50 -0500
Subject: [PATCH] login: Clear session data on expiration

This fixes an issue where the current session data is not retrieved from the
database, because it is expired. However, the session-id is not reset either.
Therefore, the session data with the new CSRF token is not updated in the
database and the user may have trouble logging in.

This problem manifests itself as a session expires. If a user clicks somewhere
in the software and their session is now expired, a redirect to the login page
is triggered. However, the CSRF token sent in the login page is not saved in
the database. So when the user logs in, they are greeted with the CSRF failure
message.

This issue is addressed by retrieving the session data from the database, but
clearing the content. Therefore it appears to the software as invalid and is
properly reset and saved to the database, thereby avoiding the errors.
---
 include/class.ostsession.php | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/include/class.ostsession.php b/include/class.ostsession.php
index dbb5cf631..5e9fba886 100644
--- a/include/class.ostsession.php
+++ b/include/class.ostsession.php
@@ -178,10 +178,15 @@ extends SessionBackend {
 
     function read($id) {
         try {
-            $this->data = SessionData::objects()->filter([
-                'session_id' => $id,
-                'session_expire__gt' => SqlFunction::NOW(),
-            ])->one();
+            $this->data = SessionData::objects()
+                ->filter(['session_id' => $id])
+                ->annotate(['age' => SqlFunction::NOW()->minus(new SqlField('session_expire'))])
+                ->one();
+            if ($this->data->age > 0) {
+                // session_expire is in the past. Pretend it is expired and
+                // reset the data. This will assist with CSRF issues
+                $this->data->session_data='';
+            }
             $this->id = $id;
         }
         catch (DoesNotExist $e) {
-- 
GitLab