CVE-2024-40624: Insufficient Information (NVD-CWE-noinfo)
value: TorrentPier is an open source BitTorrent Public/Private tracker engine, written in php. In `torrentpier/library/includes/functions.php`, `get_tracks()` uses the unsafe native PHP serialization format to deserialize user-controlled cookies. One can use phpggc and the chain Guzzle/FW1 to write PHP code to an arbitrary file, and execute commands on the system. For instance, the cookie bb_t will be deserialized when browsing to viewforum.php. This issue has been addressed in commit `ed37e6e52` which is expected to be included in release version 2.4.4. Users are advised to upgrade as soon as the new release is available. There are no known workarounds for this vulnerability.
CWE description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
Published: 2024-07-15T20:15Z
Repository: https://github.com/torrentpier/torrentpier
Language: PHP
Files changed: library/includes/functions.php, src/Legacy/Common/User.php
Commit date: 2024-07-13 19:26:57 +0700
Commit message: Merge commit from fork


Diff: diff --git a/library/includes/functions.php b/library/includes/functions.php
index a916f408..0188bcdc 100644
--- a/library/includes/functions.php
+++ b/library/includes/functions.php
@@ -38,12 +38,10 @@ function delete_avatar($user_id, $avatar_ext_id)
     return ($avatar_file && is_file($avatar_file) && unlink($avatar_file));
 }
 
 function get_tracks($type)
 {
-    static $pattern = '#^a:\d+:{[i:;\d]+}$#';
-
     switch ($type) {
         case 'topic':
             $c_name = COOKIE_TOPIC;
             break;
         case 'forum':
@@ -53,11 +51,11 @@ function get_tracks($type)
             $c_name = COOKIE_PM;
             break;
         default:
             trigger_error(__FUNCTION__ . ": invalid type '$type'", E_USER_ERROR);
     }
-    $tracks = !empty($_COOKIE[$c_name]) ? @unserialize($_COOKIE[$c_name]) : false;
+    $tracks = !empty($_COOKIE[$c_name]) ? json_decode($_COOKIE[$c_name], true) : false;
     return $tracks ?: [];
 }
 
 /**
  * Returns array with all banned users
@@ -111,11 +109,11 @@ function set_tracks($cookie_name, &$tracking_ary, $tracks = null, $val = TIMENOW
             array_pop($tracking_ary);
         }
     }
 
     if (array_diff($tracking_ary, $prev_tracking_ary)) {
-        bb_setcookie($cookie_name, serialize($tracking_ary));
+        bb_setcookie($cookie_name, json_encode($tracking_ary));
     }
 }
 
 function get_last_read($topic_id = 0, $forum_id = 0)
 {
diff --git a/src/Legacy/Common/User.php b/src/Legacy/Common/User.php
index cb085a6a..8fffaaf3 100644
--- a/src/Legacy/Common/User.php
+++ b/src/Legacy/Common/User.php
@@ -451,11 +451,11 @@ public function login(array $args, bool $mod_admin_login = false): array
     /**
      * Initialize sessiondata stored in cookies
      */
     public function get_sessiondata()
     {
-        $sd_resv = !empty($_COOKIE[COOKIE_DATA]) ? unserialize($_COOKIE[COOKIE_DATA], ['allowed_classes' => false]) : [];
+        $sd_resv = !empty($_COOKIE[COOKIE_DATA]) ? json_decode($_COOKIE[COOKIE_DATA], true) : [];
 
         // autologin_id
         if (!empty($sd_resv['uk']) && verify_id($sd_resv['uk'], LOGIN_KEY_LENGTH)) {
             $this->sessiondata['uk'] = $sd_resv['uk'];
         }
@@ -484,11 +484,11 @@ public function set_session_cookies($user_id)
                     bb_setcookie($cookie, null);
                 }
             }
         } else {
             $c_sdata_resv = !empty($_COOKIE[COOKIE_DATA]) ? $_COOKIE[COOKIE_DATA] : null;
-            $c_sdata_curr = ($this->sessiondata) ? serialize($this->sessiondata) : '';
+            $c_sdata_curr = ($this->sessiondata) ? json_encode($this->sessiondata) : '';
 
             if ($c_sdata_curr !== $c_sdata_resv) {
                 bb_setcookie(COOKIE_DATA, $c_sdata_curr, httponly: true);
             }
         }

Vulnerable code:     static $pattern = '#^a:\d+:{[i:;\d]+}$#';

    $tracks = !empty($_COOKIE[$c_name]) ? @unserialize($_COOKIE[$c_name]) : false;
        bb_setcookie($cookie_name, serialize($tracking_ary));
        $sd_resv = !empty($_COOKIE[COOKIE_DATA]) ? unserialize($_COOKIE[COOKIE_DATA], ['allowed_classes' => false]) : [];
            $c_sdata_curr = ($this->sessiondata) ? serialize($this->sessiondata) : '';
Fixed code:     $tracks = !empty($_COOKIE[$c_name]) ? json_decode($_COOKIE[$c_name], true) : false;
        bb_setcookie($cookie_name, json_encode($tracking_ary));
        $sd_resv = !empty($_COOKIE[COOKIE_DATA]) ? json_decode($_COOKIE[COOKIE_DATA], true) : [];
            $c_sdata_curr = ($this->sessiondata) ? json_encode($this->sessiondata) : '';