[SECURITY] Regenerate session id upon login if needed 19/40819/2
authorHelmut Hummel <helmut.hummel@typo3.org>
Tue, 17 Jun 2014 09:01:17 +0000 (11:01 +0200)
committerBenjamin Mack <benni@typo3.org>
Wed, 1 Jul 2015 14:20:33 +0000 (16:20 +0200)
When authenticating as a frontend user with a previously
present anonymous session, the session id is not regenerated
which leads to a possible session fixation.

This is now fixed by re-generating a new id
when a user is just authenticated but no
new session id is generated during this process.

Resolves: #59258
Releases: master, 6.2
Security-Bulletin: TYPO3-CORE-SA-2015-003
Change-Id: Iba7e3fde089b1ba8e8fe37171cbd93f7c4b31209
Reviewed-on: http://review.typo3.org/40819
Reviewed-by: Helmut Hummel <helmut.hummel@typo3.org>
Tested-by: Helmut Hummel <helmut.hummel@typo3.org>
Reviewed-by: Benjamin Mack <benni@typo3.org>
Tested-by: Benjamin Mack <benni@typo3.org>
typo3/sysext/core/Classes/Authentication/AbstractUserAuthentication.php
typo3/sysext/frontend/Classes/Authentication/FrontendUserAuthentication.php

index ed4414b..c4ce61e 100644 (file)
@@ -816,6 +816,9 @@ abstract class AbstractUserAuthentication {
                        } elseif ($haveSession) {
                                $this->user = $authInfo['userSession'];
                        }
+                       if ($activeLogin && !$this->newSessionID) {
+                               $this->regenerateSessionId();
+                       }
                        // User logged in - write that to the log!
                        if ($this->writeStdLog && $activeLogin) {
                                $this->writelog(255, 1, 0, 1, 'User %s logged in from %s (%s)', array($tempuser[$this->username_column], GeneralUtility::getIndpEnv('REMOTE_ADDR'), GeneralUtility::getIndpEnv('REMOTE_HOST')), '', '', '', -1, '', $tempuser['uid']);
@@ -867,6 +870,24 @@ abstract class AbstractUserAuthentication {
                return GeneralUtility::getRandomHexString($this->hash_length);
        }
 
+       /**
+        * Regenerate the session ID and transfer the session to new ID
+        * Call this method whenever a user proceeds to a higher authorization level
+        * e.g. when an anonymous session is now authenticated.
+        */
+       protected function regenerateSessionId() {
+               $oldSessionId = $this->id;
+               $this->id = $this->createSessionId();
+               // Update session record with new ID
+               $this->db->exec_UPDATEquery(
+                       $this->session_table,
+                       'ses_id = ' . $this->db->fullQuoteStr($oldSessionId, $this->session_table)
+                               . ' AND ses_name = ' . $this->db->fullQuoteStr($this->name, $this->session_table),
+                       array('ses_id' => $this->id)
+               );
+               $this->newSessionID = TRUE;
+       }
+
        /*************************
         *
         * User Sessions
index e4957cb..8ab941a 100644 (file)
@@ -483,6 +483,23 @@ class FrontendUserAuthentication extends \TYPO3\CMS\Core\Authentication\Abstract
        }
 
        /**
+        * Regenerate the id, take separate session data table into account
+        * and set cookie again
+        */
+       protected function regenerateSessionId() {
+               $oldSessionId = $this->id;
+               parent::regenerateSessionId();
+               // Update session data with new ID
+               $this->db->exec_UPDATEquery(
+                       'fe_session_data',
+                       'hash=' . $this->db->fullQuoteStr($oldSessionId, 'fe_session_data'),
+                       array('hash' => $this->id)
+               );
+
+               $this->dontSetCookie = FALSE;
+       }
+
+       /**
         * Executes the garbage collection of session data and session.
         * The lifetime of session data is defined by $TYPO3_CONF_VARS['FE']['sessionDataLifetime'].
         *