CVE-2023-41363: Insufficient Information (NVD-CWE-noinfo)
value: In Cerebrate 1.14, a vulnerability in UserSettingsController allows authenticated users to change user settings of other users.
CWE description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
CVSS v3 base score: 4.3
Published: 2023-08-29T05:15Z
Repository: https://github.com/cerebrate-project/cerebrate
Language: PHP
Files changed: src/Controller/UserSettingsController.php
Commit date: 2023-08-23 15:08:23 +0200
Commit message: fix: [security] user settings editable by arbitrary user fixed

- as reported by Infigo on behalf of ENISA

Diff: diff --git a/src/Controller/UserSettingsController.php b/src/Controller/UserSettingsController.php
index 7f9690ab8..6bcd197e7 100644
--- a/src/Controller/UserSettingsController.php
+++ b/src/Controller/UserSettingsController.php
@@ -98,25 +98,38 @@ class UserSettingsController extends AppController
     {
         $entity = $this->UserSettings->find()->where([
             'id' => $id
         ])->first();
 
-        if (!$this->isLoggedUserAllowedToEdit($entity)) {
-            throw new NotFoundException(__('Invalid {0}.', 'user setting'));
+        $currentUser = $this->ACL->getUser();
+        $validUsers = [];
+        $individual_ids = [];
+        if (!$currentUser['role']['perm_admin']) {
+            if ($currentUser['role']['perm_org_admin']) {
+                $validUsers = $this->Users->find('list')->select(['id', 'username'])->order(['username' => 'asc'])->where(['organisation_id' => $currentUser['organisation']['id']])->all()->toArray();
+            } else {
+                $validUsers = [$currentUser['id'] => $currentUser['username']];
+            }
+        } else {
+            $validUsers = $this->Users->find('list')->select(['id', 'username'])->order(['username' => 'asc'])->all()->toArray();
         }
 
         $entity = $this->CRUD->edit($id, [
-            'redirect' => ['action' => 'index', $entity->user_id]
+            'redirect' => ['action' => 'index', $entity->user_id],
+            'beforeSave' => function ($data) use ($validUsers) {
+                if (!in_array($data['user_id'], array_keys($validUsers))) {
+                    throw new MethodNotAllowedException(__('You cannot edit the given user.'));
+                }
+                return $data;
+            }
         ]);
         $responsePayload = $this->CRUD->getResponsePayload();
         if (!empty($responsePayload)) {
             return $responsePayload;
         }
         $dropdownData = [
-            'user' => $this->UserSettings->Users->find('list', [
-                'sort' => ['username' => 'asc']
-            ]),
+            'user' => $validUsers,
         ];
         $this->set(compact('dropdownData'));
         $this->set('user_id', $this->entity->user_id);
         $this->render('add');
     }
@@ -257,12 +270,13 @@ class UserSettingsController extends AppController
                     'id' => $setting
                 ])->first();
                 if (empty($setting)) {
                     return false;
                 }
+            } else {
+                $isAllowed = $setting->user_id == $currentUser->id;
             }
-            $isAllowed = $setting->user_id == $currentUser->id;
         }
         return $isAllowed;
     }
 
     /**

Vulnerable code:         if (!$this->isLoggedUserAllowedToEdit($entity)) {
            throw new NotFoundException(__('Invalid {0}.', 'user setting'));
            'redirect' => ['action' => 'index', $entity->user_id]
            'user' => $this->UserSettings->Users->find('list', [
                'sort' => ['username' => 'asc']
            ]),
            $isAllowed = $setting->user_id == $currentUser->id;
Fixed code:         $currentUser = $this->ACL->getUser();
        $validUsers = [];
        $individual_ids = [];
        if (!$currentUser['role']['perm_admin']) {
            if ($currentUser['role']['perm_org_admin']) {
                $validUsers = $this->Users->find('list')->select(['id', 'username'])->order(['username' => 'asc'])->where(['organisation_id' => $currentUser['organisation']['id']])->all()->toArray();
            } else {
                $validUsers = [$currentUser['id'] => $currentUser['username']];
            }
        } else {
            $validUsers = $this->Users->find('list')->select(['id', 'username'])->order(['username' => 'asc'])->all()->toArray();
            'redirect' => ['action' => 'index', $entity->user_id],
            'beforeSave' => function ($data) use ($validUsers) {
                if (!in_array($data['user_id'], array_keys($validUsers))) {
                    throw new MethodNotAllowedException(__('You cannot edit the given user.'));
                }
                return $data;
            }
            'user' => $validUsers,
            } else {
                $isAllowed = $setting->user_id == $currentUser->id;