CVE-2023-4654: Sensitive Cookie in HTTPS Session Without 'Secure' Attribute (CWE-614)
value: Sensitive Cookie in HTTPS Session Without 'Secure' Attribute in GitHub repository instantsoft/icms2 prior to 2.16.1.
CWE description: The Secure attribute for sensitive cookies in HTTPS sessions is not set, which could cause the user agent to send those cookies in plaintext over an HTTP session.
CVSS v3 base score: 3.5
Published: 2023-08-31T01:15Z
Repository: https://github.com/instantsoft/icms2
Language: PHP
Files changed: system/core/config.php, system/core/user.php
Commit date: 2023-08-16 00:47:41 +0300
Commit message: Add session regenerate after login & logout. Secure cookie if HTTPS.
close #1473
Diff: diff --git a/system/core/config.php b/system/core/config.php
index 4035c6949..df448bef8 100755
--- a/system/core/config.php
+++ b/system/core/config.php
@@ -142,11 +142,11 @@ class cmsConfig extends cmsConfigs {
             $host = empty($url_parts['path']) ? $this->host : $url_parts['scheme'] . '://' . $url_parts['host'];
             $this->upload_host = str_replace($host, '', $this->upload_host);
             $replace_upload_host_protocol = true;
         }
 
-        $this->set('document_root', rtrim(PATH, $this->root));
+        $this->set('document_root', preg_replace('#(.*)('.preg_quote($this->root).')$#u', '$1', PATH . DIRECTORY_SEPARATOR));
         $this->set('root_path', PATH . DIRECTORY_SEPARATOR);
         $this->set('system_path', $this->root_path . 'system/');
         $this->set('upload_path', $this->document_root . $this->upload_root);
         $this->set('cache_path', $this->document_root . $this->cache_root);
 
diff --git a/system/core/user.php b/system/core/user.php
index 408665f4d..c7466d509 100755
--- a/system/core/user.php
+++ b/system/core/user.php
@@ -263,10 +263,12 @@ class cmsUser {
 
         $user = cmsEventsManager::hook('user_login', $user);
 
         self::setUserSession($user, $user['ip']);
 
+        self::sessionRegenerate();
+
         return intval($user['id']);
     }
 
     /**
      * Авторизует пользователя
@@ -341,10 +343,12 @@ class cmsUser {
         $model->updateUserIp($user['id']);
 
         self::getInstance()->id = $user['id'];
         self::getInstance()->is_logged = true;
 
+        self::sessionRegenerate();
+
         return true;
     }
 
     /**
      * Выход пользователя
@@ -382,10 +386,12 @@ class cmsUser {
             self::$auth_token = null;
         }
 
         self::sessionUnset('user');
 
+        self::sessionRegenerate();
+
         return true;
     }
 
 //============================================================================//
 //============================================================================//
@@ -484,10 +490,23 @@ class cmsUser {
         if ($session_time_zone && $session_time_zone !== $config->time_zone) {
             $config->set('time_zone', $session_time_zone);
         }
     }
 
+    public static function sessionRegenerate() {
+
+        session_regenerate_id(false);
+
+        $id = session_id();
+
+        session_write_close();
+
+        session_id($id);
+
+        session_start();
+    }
+
     public static function sessionSet($key, $value) {
 
         if (strpos($key, ':') === false) {
             $_SESSION[$key] = $value;
         } else {
@@ -566,11 +585,11 @@ class cmsUser {
             return setcookie('icms[' . $key . ']', $value, [
                 'expires'  => time() + $time,
                 'path'     => $path,
                 'domain'   => $domain,
                 'samesite' => 'Lax',
-                'secure'   => false,
+                'secure'   => cmsConfig::isSecureProtocol(),
                 'httponly' => $http_only
             ]);
         }
     }
 

Vulnerable code:         $this->set('document_root', rtrim(PATH, $this->root));
                'secure'   => false,
Fixed code:         $this->set('document_root', preg_replace('#(.*)('.preg_quote($this->root).')$#u', '$1', PATH . DIRECTORY_SEPARATOR));
        self::sessionRegenerate();

        self::sessionRegenerate();

        self::sessionRegenerate();

    public static function sessionRegenerate() {

        session_regenerate_id(false);

        $id = session_id();

        session_write_close();

        session_id($id);

        session_start();
    }

                'secure'   => cmsConfig::isSecureProtocol(),