From a7efe1faf9c5c5d101764fa7d2cf13e46774e727 Mon Sep 17 00:00:00 2001
From: Alexandre Dulaunoy <a@foo.be>
Date: Mon, 31 Jan 2022 10:12:01 +0100
Subject: [PATCH 1/5] Update INSTALL.md

---
 INSTALL/INSTALL.md | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/INSTALL/INSTALL.md b/INSTALL/INSTALL.md
index f4cef5f..8a9c901 100644
--- a/INSTALL/INSTALL.md
+++ b/INSTALL/INSTALL.md
@@ -1,7 +1,9 @@
 ## Requirements
 
 An Ubuntu server (18.04/20.04 should both work fine) - though other linux installations should work too.
+
 - apache2 (or nginx), mysql/mariadb, sqlite need to be installed and running
+- php version 8+ is required
 - php extensions for intl, mysql, sqlite3, mbstring, xml need to be installed and running
 - php extention for curl (not required but makes composer run a little faster)
 - composer

From e60d97c214f9ac6df90c87241b3b3554afc06238 Mon Sep 17 00:00:00 2001
From: iglocska <andras.iklody@gmail.com>
Date: Thu, 3 Feb 2022 23:54:47 +0100
Subject: [PATCH 2/5] fix: [security] genericForm reflected XSS in form
 descriptions for user controlled descriptions

- accessible via the MISP local tool setting change
- sanitise the description

- as reported by Dawid Czarnecki from Zigrin Security
---
 templates/element/genericElements/Form/genericForm.php | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/templates/element/genericElements/Form/genericForm.php b/templates/element/genericElements/Form/genericForm.php
index 2e509ba..7d7552d 100644
--- a/templates/element/genericElements/Form/genericForm.php
+++ b/templates/element/genericElements/Form/genericForm.php
@@ -106,7 +106,7 @@
                 '%s%s%s%s%s%s',
                 empty($data['description']) ? '' : sprintf(
                     '<div class="pb-2 fw-light">%s</div>',
-                    $data['description']
+                    h($data['description'])
                 ),
                 $ajaxFlashMessage,
                 $formCreate,
@@ -131,7 +131,7 @@
             '%s%s%s%s%s%s',
             empty($data['description']) ? '' : sprintf(
                 '<div class="pb-2">%s</div>',
-                $data['description']
+                h($data['description'])
             ),
             $ajaxFlashMessage,
             $formCreate,
@@ -157,7 +157,7 @@
             $ajaxFlashMessage,
             empty($data['description']) ? '' : sprintf(
                 '<div class="pb-3 fw-light">%s</div>',
-                $data['description']
+                h($data['description'])
             ),
             sprintf('<div class="panel">%s</div>', $fieldsString),
             empty($metaTemplateString) ? '' : $this->element(

From 15190b930ebada9e8d294db57c96832799d9d93e Mon Sep 17 00:00:00 2001
From: iglocska <andras.iklody@gmail.com>
Date: Fri, 4 Feb 2022 00:16:24 +0100
Subject: [PATCH 3/5] fix: [security] Sharing group ACL fixes

- added indirect object reference protection
- added correct ACL functionalities to delete, addOrg, removeOrg

- as reported by Dawid Czarnecki from Zigrin Security
---
 src/Controller/Component/CRUDComponent.php |  6 +++
 src/Controller/SharingGroupsController.php | 44 +++++++++++++++++++++-
 2 files changed, 48 insertions(+), 2 deletions(-)

diff --git a/src/Controller/Component/CRUDComponent.php b/src/Controller/Component/CRUDComponent.php
index 1a1e733..14369ab 100644
--- a/src/Controller/Component/CRUDComponent.php
+++ b/src/Controller/Component/CRUDComponent.php
@@ -420,10 +420,16 @@ class CRUDComponent extends Component
         }
 
         $data = $this->Table->get($id, $params);
+        if (empty($data)) {
+            throw new NotFoundException(__('Invalid {0}.', $this->ObjectAlias));
+        }
         $data = $this->attachMetaData($id, $data);
         if (isset($params['afterFind'])) {
             $data = $params['afterFind']($data);
         }
+        if (empty($data)) {
+            throw new NotFoundException(__('Invalid {0}.', $this->ObjectAlias));
+        }
         if ($this->Controller->ParamHandler->isRest()) {
             $this->Controller->restResponsePayload = $this->RestResponse->viewData($data, 'json');
         }
diff --git a/src/Controller/SharingGroupsController.php b/src/Controller/SharingGroupsController.php
index 764f0e6..aa96cb4 100644
--- a/src/Controller/SharingGroupsController.php
+++ b/src/Controller/SharingGroupsController.php
@@ -7,6 +7,7 @@ use Cake\Utility\Hash;
 use Cake\Utility\Text;
 use \Cake\Database\Expression\QueryExpression;
 use Cake\Error\Debugger;
+use Cake\Http\Exception\NotFoundException;
 
 class SharingGroupsController extends AppController
 {
@@ -54,8 +55,25 @@ class SharingGroupsController extends AppController
 
     public function view($id)
     {
+        $currentUser = $this->ACL->getUser();
         $this->CRUD->view($id, [
-            'contain' => ['SharingGroupOrgs', 'Organisations', 'Users' => ['fields' => ['id', 'username']]]
+            'contain' => ['SharingGroupOrgs', 'Organisations', 'Users' => ['fields' => ['id', 'username']]],
+            'afterFind' => function($data) use ($currentUser) {
+                if (empty($currentUser['role']['perm_admin'])) {
+                    $orgFround = false;
+                    if (!empty($data['sharing_group_orgs'])) {
+                        foreach ($data['sharing_group_orgs'] as $org) {
+                            if ($org['id'] === $currentUser['organisation_id']) {
+                                $orgFound = true;
+                            }
+                        }
+                    }
+                    if ($data['organisation_id'] !== $currentUser['organisation_id'] && !$orgFround) {
+                        return null;
+                    }
+                }
+                return $data;
+            }
         ]);
         $responsePayload = $this->CRUD->getResponsePayload();
         if (!empty($responsePayload)) {
@@ -87,7 +105,11 @@ class SharingGroupsController extends AppController
 
     public function delete($id)
     {
-        $this->CRUD->delete($id);
+        $currentUser = $this->ACL->getUser();
+        if (empty($currentUser['role']['perm_admin'])) {
+            $params['conditions'] = ['organisation_id' => $currentUser['organisation_id']];
+        }
+        $this->CRUD->delete($id, $params);
         $responsePayload = $this->CRUD->getResponsePayload();
         if (!empty($responsePayload)) {
             return $responsePayload;
@@ -97,9 +119,18 @@ class SharingGroupsController extends AppController
 
     public function addOrg($id)
     {
+        $currentUser = $this->ACL->getUser();
         $sharingGroup = $this->SharingGroups->get($id, [
             'contain' => 'SharingGroupOrgs'
         ]);
+        if (empty($currentUser['role']['perm_admin'])) {
+            if ($sharingGroup['organisation_id'] !== $currentUser['organisation_id']) {
+                $sharingGroup = null;
+            }
+        }
+        if (empty($sharingGroup)) {
+            throw new NotFoundException(__('Invalid SharingGroup.'));
+        }
         $conditions = [];
         $containedOrgIds = array_values(\Cake\Utility\Hash::extract($sharingGroup, 'sharing_group_orgs.{n}.id'));
         if (!empty($containedOrgIds)) {
@@ -156,9 +187,18 @@ class SharingGroupsController extends AppController
 
     public function removeOrg($id, $org_id)
     {
+        $currentUser = $this->ACL->getUser();
         $sharingGroup = $this->SharingGroups->get($id, [
             'contain' => 'SharingGroupOrgs'
         ]);
+        if (empty($currentUser['role']['perm_admin'])) {
+            if ($sharingGroup['organisation_id'] !== $currentUser['organisation_id']) {
+                $sharingGroup = null;
+            }
+        }
+        if (empty($sharingGroup)) {
+            throw new NotFoundException(__('Invalid SharingGroup.'));
+        }
         if ($this->request->is('post')) {
             $org = $this->SharingGroups->SharingGroupOrgs->get($org_id);
             $result = (bool)$this->SharingGroups->SharingGroupOrgs->unlink($sharingGroup, [$org]);

From a2632349175e574cd6305fa459cd7610ea09ab61 Mon Sep 17 00:00:00 2001
From: iglocska <andras.iklody@gmail.com>
Date: Fri, 4 Feb 2022 00:36:31 +0100
Subject: [PATCH 4/5] fix: [security] open endpoints should only be open when
 enabled

- as reported by Dawid Czarnecki from Zigrin Security
---
 src/Controller/Open/IndividualsController.php   | 6 +++++-
 src/Controller/Open/OrganisationsController.php | 6 +++++-
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/Controller/Open/IndividualsController.php b/src/Controller/Open/IndividualsController.php
index 28cd51d..79af257 100644
--- a/src/Controller/Open/IndividualsController.php
+++ b/src/Controller/Open/IndividualsController.php
@@ -11,13 +11,17 @@ use Cake\Http\Exception\NotFoundException;
 use Cake\Http\Exception\MethodNotAllowedException;
 use Cake\Http\Exception\ForbiddenException;
 use Cake\Event\EventInterface;
+use Cake\Core\Configure;
 
 class IndividualsController extends AppController
 {
     public function beforeFilter(EventInterface $event)
     {
         parent::beforeFilter($event);
-        $this->Authentication->allowUnauthenticated(['index']);
+        $open = Configure::read('Cerebrate.open');
+        if (!empty($open) && in_array('individuals', $open)) {
+            $this->Authentication->allowUnauthenticated(['index']);
+        }
     }
 
     public function index()
diff --git a/src/Controller/Open/OrganisationsController.php b/src/Controller/Open/OrganisationsController.php
index ad22f42..facda8a 100644
--- a/src/Controller/Open/OrganisationsController.php
+++ b/src/Controller/Open/OrganisationsController.php
@@ -10,13 +10,17 @@ use Cake\Http\Exception\NotFoundException;
 use Cake\Http\Exception\MethodNotAllowedException;
 use Cake\Http\Exception\ForbiddenException;
 use Cake\Event\EventInterface;
+use Cake\Core\Configure;
 
 class OrganisationsController extends AppController
 {
     public function beforeFilter(EventInterface $event)
     {
         parent::beforeFilter($event);
-        $this->Authentication->allowUnauthenticated(['index']);
+        $open = Configure::read('Cerebrate.open');
+        if (!empty($open) && in_array('organisations', $open)) {
+            $this->Authentication->allowUnauthenticated(['index']);
+        }
     }
 
     public function index()

From 88f3cc794486276a1f7e7331adb8ecb2dabd672f Mon Sep 17 00:00:00 2001
From: iglocska <andras.iklody@gmail.com>
Date: Fri, 4 Feb 2022 00:45:42 +0100
Subject: [PATCH 5/5] fix: [security] user settings allow enumeration of
 usernames

- as reported by Dawid Czarnecki from Zigrin Security
---
 src/Controller/UserSettingsController.php | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/src/Controller/UserSettingsController.php b/src/Controller/UserSettingsController.php
index 02affce..7f9690a 100644
--- a/src/Controller/UserSettingsController.php
+++ b/src/Controller/UserSettingsController.php
@@ -36,9 +36,16 @@ class UserSettingsController extends AppController
             return $responsePayload;
         }
         if (!empty($this->request->getQuery('Users_id'))) {
-            $settingsForUser = $this->UserSettings->Users->find()->where([
+            $conditions = [
                 'id' => $this->request->getQuery('Users_id')
-            ])->first();
+            ];
+            if (empty($currentUser['role']['perm_admin'])) {
+                $conditions['organisation_id'] = $currentUser['organisation_id'];
+            }
+            $settingsForUser = $this->UserSettings->Users->find()->where($conditions)->first();
+            if (empty($settingsForUser)) {
+                throw new NotFoundException(__('Invalid {0}.', __('user')));
+            }
             $this->set('settingsForUser', $settingsForUser);
         }
     }
@@ -233,7 +240,7 @@ class UserSettingsController extends AppController
     }
 
     /**
-     * isLoggedUserAllowedToEdit 
+     * isLoggedUserAllowedToEdit
      *
      * @param int|\App\Model\Entity\UserSetting $setting
      * @return boolean