CVE-2021-33394: Session Fixation (CWE-384)
value: Cubecart 6.4.2 allows Session Fixation. The application does not generate a new session cookie after the user is logged in. A malicious user is able to create a new session cookie value and inject it to a victim. After the victim logs in, the injected cookie becomes valid, giving the attacker access to the user's account through the active session.
CWE description: Authenticating a user, or otherwise establishing a new user session, without invalidating any existing session identifier gives an attacker the opportunity to steal authenticated sessions.
CVSS v3 base score: 5.4
Published: 2021-05-27T19:15Z
Repository: https://github.com/cubecart/v6
Language: PHP
Files changed: classes/admin.class.php, classes/session.class.php, classes/user.class.php
Commit date: 2021-05-20 08:15:48 +0100
Commit message: #2870 - session fixation

Diff: diff --git a/classes/admin.class.php b/classes/admin.class.php
index 28535a40..cfa928ef 100755
--- a/classes/admin.class.php
+++ b/classes/admin.class.php
@@ -347,10 +347,11 @@ class Admin
             $result = $GLOBALS['db']->select('CubeCart_admin_users', array('admin_id', 'customer_id', 'logins', 'new_password'), array('username' => $username, 'password' => $hash_password, 'status' => '1'));
             $GLOBALS['session']->blocker($username, 0, (bool)$result, Session::BLOCKER_BACKEND, $GLOBALS['config']->get('config', 'bfattempts'), $GLOBALS['config']->get('config', 'bftime'));
             if ($result) {
                 if (!$GLOBALS['session']->blocked()) {
                     $this->_logged_in = true;
+                    $GLOBALS['session']->regenerateSessionId();
                     $update = array(
                         'blockTime'  => 0,
                         'browser'  => htmlspecialchars($_SERVER['HTTP_USER_AGENT']),
                         'failLevel'  => 0,
                         'session_id' => $GLOBALS['session']->getId(),
diff --git a/classes/session.class.php b/classes/session.class.php
index 6b00b251..b08f619e 100755
--- a/classes/session.class.php
+++ b/classes/session.class.php
@@ -526,10 +526,17 @@ class Session
         $namespace = $this->_namespace($namespace);
 
         return empty($_SESSION[$namespace][$name]);
     }
 
+    public function regenerateSessionId() {
+        $old_session = $this->getId();
+        session_regenerate_id();
+        Database::getInstance()->update('CubeCart_sessions', array('session_id' => $this->getId()), array('session_id' => $old_session), false);
+        $this->set_cookie(session_name(), session_id(), time()+$this->_session_timeout);
+    }
+
     /**
      * Set a session value to something
      *
      * @param string $name
      * @param string $value
diff --git a/classes/user.class.php b/classes/user.class.php
index 9dd235b5..040bfe61 100755
--- a/classes/user.class.php
+++ b/classes/user.class.php
@@ -273,10 +273,11 @@ class User
                 if ($remember || $from_cookie) {
                     $GLOBALS['session']->set_cookie('username', $user[0]['email'], time() + (3600*24*30));
                 }
                 if (!$GLOBALS['session']->blocked()) {
                     // possibly replaceable with session_set_save_handler?
+                    $GLOBALS['session']->regenerateSessionId();
                     $GLOBALS['db']->update('CubeCart_sessions', array('customer_id' => $user[0]['customer_id']), array('session_id' => $GLOBALS['session']->getId()));
                     $GLOBALS['db']->update('CubeCart_cookie_consent', array('customer_id' => $user[0]['customer_id']), array('session_id' => $GLOBALS['session']->getId()));
                     $GLOBALS['session']->set('language', $user[0]['language'], 'client');
                     // Load user data
                     $this->_load();

Fixed code:                     $GLOBALS['session']->regenerateSessionId();
    public function regenerateSessionId() {
        $old_session = $this->getId();
        session_regenerate_id();
        Database::getInstance()->update('CubeCart_sessions', array('session_id' => $this->getId()), array('session_id' => $old_session), false);
        $this->set_cookie(session_name(), session_id(), time()+$this->_session_timeout);
    }

                    $GLOBALS['session']->regenerateSessionId();