Vulnerability: A cross-site scripting (XSS) vulnerability exists in MISP v2.4.128 in app/Controller/UserSettingsController.php at SetHomePage() function. Due to a lack of controller validation in "path" parameter, an attacker can execute malicious JavaScript code.
Vulnerability ID: CVE-2020-24085
CWE: CWE-79
Severity score: 2.9
Project: https://github.com/MISP/MISP
Published: 2021-01-26
File: app/Controller/UserSettingsController.php
Commit message: fix: [security] xss fix missing part of solution

- the previous fix to the xss in the homepage setter was lacking the controller changes due to a partial commit (#bf4610c947c7dc372c4078f363d2dff6ae0703a8)

  - as originally discovered by Mislav Božičević <mislav.bozicevic@nn.cz>
  - persistence of the vulnerability after the lacking fix reported by DIEGO JURADO PALLARES from Ciberinteligencia
Commit author: iglocska

Vulnerable version (before fix):
 class UserSettingsController extends AppController     public function beforeFilter()     {         parent::beforeFilter();         $this->Security->unlockedActions = array_merge($this->Security->unlockedActions, array('setHomePage'));     }      public function index() public function delete($id = false)      public function setHomePage()     {         if (!$this->request->is('post')) {             throw new MethodNotAllowedException(__('This endpoint only aaccepts POST requests.'));         }         if (empty($this->request->data['path'])) {             $this->request->data = array('path' => $this->request->data);         }         if (empty($this->request->data['path'])) {             throw new InvalidArgumentException(__('No path POSTed.'));         }         $setting = array(             'UserSetting' => array(                 'user_id' => $this->Auth->user('id'),                 'setting' => 'homepage',                 'value' => json_encode(array('path' => $this->request->data['path']))             )         );         $result = $this->UserSetting->setSetting($this->Auth->user(), $setting);         return $this->RestResponse->saveSuccessResponse('UserSettings', 'setHomePage', false, $this->response->type(), 'Homepage set to ' . $this->request->data['path']);     } }

Fixed version (after fix):
 class UserSettingsController extends AppController     public function beforeFilter()     {         parent::beforeFilter();     }      public function index() public function delete($id = false)      public function setHomePage()     {         if ($this->request->is('post')) {             if (isset($this->request->data['UserSetting'])) {                 $this->request->data = $this->request->data['UserSetting'];             }             if (!isset($this->request->data['path'])) {                 $this->request->data = array('path' => $this->request->data);             }             if (empty($this->request->data['path'])) {                 throw new InvalidArgumentException(__('No path POSTed.'));             }             $setting = array(                 'UserSetting' => array(                     'user_id' => $this->Auth->user('id'),                     'setting' => 'homepage',                     'value' => json_encode(array('path' => $this->request->data['path']))                 )             );             $result = $this->UserSetting->setSetting($this->Auth->user(), $setting);             return $this->RestResponse->saveSuccessResponse('UserSettings', 'setHomePage', false, $this->response->type(), 'Homepage set to ' . $this->request->data['path']);         } else {             $this->layout = false;         }     } }

Patch:
patch: @@ -28,7 +28,6 @@ class UserSettingsController extends AppController
     public function beforeFilter()
     {
         parent::beforeFilter();
-        $this->Security->unlockedActions = array_merge($this->Security->unlockedActions, array('setHomePage'));
     }
 
     public function index()
@@ -325,23 +324,27 @@ public function delete($id = false)
 
     public function setHomePage()
     {
-        if (!$this->request->is('post')) {
-            throw new MethodNotAllowedException(__('This endpoint only aaccepts POST requests.'));
-        }
-        if (empty($this->request->data['path'])) {
-            $this->request->data = array('path' => $this->request->data);
-        }
-        if (empty($this->request->data['path'])) {
-            throw new InvalidArgumentException(__('No path POSTed.'));
+        if ($this->request->is('post')) {
+            if (isset($this->request->data['UserSetting'])) {
+                $this->request->data = $this->request->data['UserSetting'];
+            }
+            if (!isset($this->request->data['path'])) {
+                $this->request->data = array('path' => $this->request->data);
+            }
+            if (empty($this->request->data['path'])) {
+                throw new InvalidArgumentException(__('No path POSTed.'));
+            }
+            $setting = array(
+                'UserSetting' => array(
+                    'user_id' => $this->Auth->user('id'),
+                    'setting' => 'homepage',
+                    'value' => json_encode(array('path' => $this->request->data['path']))
+                )
+            );
+            $result = $this->UserSetting->setSetting($this->Auth->user(), $setting);
+            return $this->RestResponse->saveSuccessResponse('UserSettings', 'setHomePage', false, $this->response->type(), 'Homepage set to ' . $this->request->data['path']);
+        } else {
+            $this->layout = false;
         }
-        $setting = array(
-            'UserSetting' => array(
-                'user_id' => $this->Auth->user('id'),
-                'setting' => 'homepage',
-                'value' => json_encode(array('path' => $this->request->data['path']))
-            )
-        );
-        $result = $this->UserSetting->setSetting($this->Auth->user(), $setting);
-        return $this->RestResponse->saveSuccessResponse('UserSettings', 'setHomePage', false, $this->response->type(), 'Homepage set to ' . $this->request->data['path']);
     }
 }
path: app/Controller/UserSettingsController.php