CVE-2023-1463: Authorization Bypass Through User-Controlled Key (CWE-639)
value: Authorization Bypass Through User-Controlled Key in GitHub repository nilsteampassnet/teampass prior to 3.0.0.23.
CWE description: The system's authorization functionality does not prevent one user from gaining access to another user's data or record by modifying the key value identifying the data.
CVSS v3 base score: 5.4
Published: 2023-03-17T12:15Z
Repository: https://github.com/nilsteampassnet/teampass
Language: PHP
Files changed: error.php, includes/core/load.js.php, includes/core/logout.php, install/css/install.css, install/upgrade.php
Commit date: 2023-03-17 11:40:49 +0100
Commit message: 3.0.0.23

Fix for identified CWE-285: Improper Authorization

Diff: diff --git a/error.php b/error.php
index b5e44337c..76f55ed1b 100755
--- a/error.php
+++ b/error.php
@@ -101,11 +101,11 @@ if (
 
             <div class="error-content">
                 <h3><i class="fa fa-warning text-danger"></i> Oops! <?php echo $errorCode; ?>.</h3>
 
                 <p>
-                    For security reason, you have been disconnected. Click to <a href="./includes/core/logout.php?user_id=" + <?php echo isset($_SESSION['user_id']) === true ? $_SESSION['user_id'] : ''; ?>>log in</a>.
+                    For security reason, you have been disconnected. Click to <a href="./includes/core/logout.php?token=" + <?php echo isset($_SESSION['key']) === true ? $_SESSION['key'] : ''; ?>>log in</a>.
                 </p>
 
             </div>
             <!-- /.error-content -->
         </div>
diff --git a/includes/core/load.js.php b/includes/core/load.js.php
index c22b0a691..5905f481c 100755
--- a/includes/core/load.js.php
+++ b/includes/core/load.js.php
@@ -480,11 +480,11 @@ if (
             } else if ($(this).data('name') === 'profile') {
                 // Show profile page
                 document.location.href = "index.php?page=profile";
             } else if ($(this).data('name') === 'logout') {
                 // Logout directly to login form
-                window.location.href = "./includes/core/logout.php?user_id=" + <?php echo $_SESSION['user_id']; ?>
+                window.location.href = "./includes/core/logout.php?token=<?php echo $_SESSION['key']; ?>";
             }
         }
     });
 
     $('.close-element').click(function() {
@@ -1672,11 +1672,11 @@ if (
                         '', {
                             timeOut: 4000
                         }
                     );
 
-                    window.location.href = "./includes/core/logout.php?user_id=" + <?php echo $_SESSION['user_id']; ?>
+                    window.location.href = "./includes/core/logout.php?token=" + <?php echo $_SESSION['key']; ?>
                 } else if (store.get('teampassUser').admin_user_password) {
                     // now select if sending by email
                     $('#dialog-admin-change-user-password-info').html('<i class="fas fa-envelope-open-text fa-lg warning mr-2"></i><?php echo langHdl('information'); ?><br><br>'+
                     '<i class="fas fa-info-circle mr-2"></i><?php echo langHdl('send_user_password_by_email'); ?>'+
                     '<div class="row">'+
diff --git a/includes/core/logout.php b/includes/core/logout.php
index a68b1821c..99a2f31fd 100755
--- a/includes/core/logout.php
+++ b/includes/core/logout.php
@@ -36,14 +36,15 @@ $get = [];
 $get['user_id'] = $superGlobal->get('user_id', 'GET');
 
 // Update table by deleting ID
 if (isset($_SESSION['user_id']) === true && empty($_SESSION['user_id']) === false) {
     $user_id = $_SESSION['user_id'];
-} elseif (isset($get['user_id']) === true && empty($get['user_id']) === false) {
-    $user_id = $get['user_id'];
+} elseif (isset($get['token']) === true && empty($get['token']) === false) {
+    $user_token = $get['token'];
 } else {
     $user_id = '';
+    $user_token = '';
 }
 
 if (empty($user_id) === false && isset($_SESSION['CPM']) === true) {
     // connect to the server
     include_once '../../sources/main.functions.php';
@@ -63,12 +64,13 @@ if (empty($user_id) === false && isset($_SESSION['CPM']) === true) {
         [
             'key_tempo' => '',
             'timestamp' => '',
             'session_end' => '',
         ],
-        'id=%i',
-        $user_id
+        'id=%i || key_tempo=%s',
+        $user_id,
+        $user_token
     );
     //Log into DB the user's disconnection
     if (isset($SETTINGS['log_connections']) === true
         && (int) $SETTINGS['log_connections'] === 1
     ) {
diff --git a/install/css/install.css b/install/css/install.css
index 8ba5a27f9..3b50c52f2 100755
--- a/install/css/install.css
+++ b/install/css/install.css
@@ -119,13 +119,5 @@ h5 {
 }
 
 .hidden {
   display: none;
 }
-
-.center-screen {
-	position:absolute;
-	top:50%;
-	left: 50%;
-	margin-right: -50%;
-	transform: translate(-50%, -50%);
-}
\ No newline at end of file
diff --git a/install/upgrade.php b/install/upgrade.php
index b07964958..54b7265e1 100755
--- a/install/upgrade.php
+++ b/install/upgrade.php
@@ -274,11 +274,40 @@ if (!isset($_GET['step']) && !isset($post_step)) {
             <div class="col-12">
                 <div class="card card-',$dbSettings === true ? 'primary' : 'warning','">
                     <div class="card-header">
                         <h5>DataBase Informations</h5>
                     </div>
-                    <div class="card-body">';
+                    <div class="card-body">
+                        <!--<div class="form-group">
+                            <label>Host</label>
+                            <input type="text" class="form-control" name="db_host" id="db_host" class="ui-widget" value="'.DB_HOST.'">
+                        </div>
+                        
+                        <div class="form-group">
+                            <label>Database name</label>
+                            <input type="text" class="form-control" name="db_name" id="db_name" class="ui-widget" value="'.DB_NAME.'">
+                        </div>
+                        
+                        <div class="form-group">
+                            <label>Login</label>
+                            <input type="text" class="form-control" name="db_user" id="db_user" class="ui-widget" value="'.DB_USER.'">
+                        </div>
+                        
+                        <div class="form-group">
+                            <label>Password</label>
+                            <input type="text" class="form-control" name="db_pw" id="db_pw" class="ui-widget" value="'.$visible_pwd.'">
+                        </div>
+                        
+                        <div class="form-group">
+                            <label>Prefix</label>
+                            <input type="text" class="form-control" name="db_prefix" id="db_prefix" class="ui-widget" value="'.DB_PREFIX.'">
+                        </div>
+                        
+                        <div class="form-group">
+                            <label>Port</label>
+                            <input type="text" class="form-control" name="db_port" id="db_port" class="ui-widget" value="'.DB_PORT.'">
+                        </div>-->';
 
     // check if all database  info are available
     if ($dbSettings === true) {
         echo '
                         <div>

Vulnerable code:                     For security reason, you have been disconnected. Click to <a href="./includes/core/logout.php?user_id=" + <?php echo isset($_SESSION['user_id']) === true ? $_SESSION['user_id'] : ''; ?>>log in</a>.
                window.location.href = "./includes/core/logout.php?user_id=" + <?php echo $_SESSION['user_id']; ?>
                    window.location.href = "./includes/core/logout.php?user_id=" + <?php echo $_SESSION['user_id']; ?>
} elseif (isset($get['user_id']) === true && empty($get['user_id']) === false) {
    $user_id = $get['user_id'];
        'id=%i',
        $user_id

.center-screen {
	position:absolute;
	top:50%;
	left: 50%;
	margin-right: -50%;
	transform: translate(-50%, -50%);
}
                    <div class="card-body">';
Fixed code:                     For security reason, you have been disconnected. Click to <a href="./includes/core/logout.php?token=" + <?php echo isset($_SESSION['key']) === true ? $_SESSION['key'] : ''; ?>>log in</a>.
                window.location.href = "./includes/core/logout.php?token=<?php echo $_SESSION['key']; ?>";
                    window.location.href = "./includes/core/logout.php?token=" + <?php echo $_SESSION['key']; ?>
} elseif (isset($get['token']) === true && empty($get['token']) === false) {
    $user_token = $get['token'];
    $user_token = '';
        'id=%i || key_tempo=%s',
        $user_id,
        $user_token
                    <div class="card-body">
                        <!--<div class="form-group">
                            <label>Host</label>
                            <input type="text" class="form-control" name="db_host" id="db_host" class="ui-widget" value="'.DB_HOST.'">
                        </div>
                        
                        <div class="form-group">
                            <label>Database name</label>
                            <input type="text" class="form-control" name="db_name" id="db_name" class="ui-widget" value="'.DB_NAME.'">
                        </div>
                        
                        <div class="form-group">
                            <label>Login</label>
                            <input type="text" class="form-control" name="db_user" id="db_user" class="ui-widget" value="'.DB_USER.'">
                        </div>
                        
                        <div class="form-group">
                            <label>Password</label>
                            <input type="text" class="form-control" name="db_pw" id="db_pw" class="ui-widget" value="'.$visible_pwd.'">
                        </div>
                        
                        <div class="form-group">
                            <label>Prefix</label>
                            <input type="text" class="form-control" name="db_prefix" id="db_prefix" class="ui-widget" value="'.DB_PREFIX.'">
                        </div>
                        
                        <div class="form-group">
                            <label>Port</label>
                            <input type="text" class="form-control" name="db_port" id="db_port" class="ui-widget" value="'.DB_PORT.'">
                        </div>-->';