CVE-2020-29006: Missing Authorization (CWE-862)
value: MISP before 2.4.135 lacks an ACL check, related to app/Controller/GalaxyElementsController.php and app/Model/GalaxyElement.php.
CWE description: The product does not perform an authorization check when an actor attempts to access a resource or perform an action.
CVSS v3 base score: 9.8
Published: 2020-11-24T15:15Z
Repository: https://github.com/MISP/MISP
Language: PHP
Files changed: app/Controller/GalaxyElementsController.php, app/Model/GalaxyElement.php
Commit date: 2020-11-24 12:15:42 +0100
Commit message: fix: [security] Make cluster's elements adhere to ACL

Diff: diff --git a/app/Controller/GalaxyElementsController.php b/app/Controller/GalaxyElementsController.php
index dd3287f8b90..68c3759c67f 100644
--- a/app/Controller/GalaxyElementsController.php
+++ b/app/Controller/GalaxyElementsController.php
@@ -12,13 +12,15 @@ class GalaxyElementsController extends AppController
             'order' => array(
                 'GalaxyElement.key' => 'ASC'
             )
     );
 
-    public function index($id)
+    public function index($clusterId)
     {
-        $this->paginate['conditions'] = array('GalaxyElement.galaxy_cluster_id' => $id);
+        $aclConditions = $this->GalaxyElement->buildClusterConditions($this->Auth->user(), $clusterId);
+        $this->paginate['conditions'] = [$aclConditions];
+        $this->paginate['contain'] = ['GalaxyCluster' => ['fields' => ['id', 'distribution', 'org_id']]];
         $clusters = $this->paginate();
         $this->set('list', $clusters);
         if ($this->request->is('ajax')) {
             $this->layout = 'ajax';
             $this->render('ajax/index');
diff --git a/app/Model/GalaxyElement.php b/app/Model/GalaxyElement.php
index ea6f967f815..5b0207b43db 100644
--- a/app/Model/GalaxyElement.php
+++ b/app/Model/GalaxyElement.php
@@ -93,6 +93,39 @@ class GalaxyElement extends AppModel
                 'galaxy_cluster_id' => $clusterId,
             );
         }
         $this->saveMany($tempElements);
     }
+
+    public function buildACLConditions($user)
+    {
+        $conditions = [];
+        if (!$user['Role']['perm_site_admin']) {
+            $conditions = $this->GalaxyCluster->buildConditions($user);
+        }
+        return $conditions;
+    }
+
+    public function buildClusterConditions($user, $clusterId)
+    {
+        return [
+            $this->buildACLConditions($user),
+            'GalaxyCluster.id' => $clusterId
+        ];
+    }
+
+    public function fetchElements(array $user, $clusterId)
+    {
+        $params = array(
+            'conditions' => $this->buildClusterConditions($user, $clusterId),
+            'contain' => ['GalaxyCluster' => ['fields' => ['id', 'distribution', 'org_id']]],
+            'recursive' => -1
+        );
+        $elements = $this->find('all', $params);
+        foreach ($elements as $i => $element) {
+            $elements[$i] = $elements[$i]['GalaxyElement'];
+            unset($elements[$i]['GalaxyCluster']);
+            unset($elements[$i]['GalaxyElement']);
+        }
+        return $elements;
+    }
 }

Vulnerable code:     public function index($id)
        $this->paginate['conditions'] = array('GalaxyElement.galaxy_cluster_id' => $id);
Fixed code:     public function index($clusterId)
        $aclConditions = $this->GalaxyElement->buildClusterConditions($this->Auth->user(), $clusterId);
        $this->paginate['conditions'] = [$aclConditions];
        $this->paginate['contain'] = ['GalaxyCluster' => ['fields' => ['id', 'distribution', 'org_id']]];

    public function buildACLConditions($user)
    {
        $conditions = [];
        if (!$user['Role']['perm_site_admin']) {
            $conditions = $this->GalaxyCluster->buildConditions($user);
        }
        return $conditions;
    }

    public function buildClusterConditions($user, $clusterId)
    {
        return [
            $this->buildACLConditions($user),
            'GalaxyCluster.id' => $clusterId
        ];
    }

    public function fetchElements(array $user, $clusterId)
    {
        $params = array(
            'conditions' => $this->buildClusterConditions($user, $clusterId),
            'contain' => ['GalaxyCluster' => ['fields' => ['id', 'distribution', 'org_id']]],
            'recursive' => -1
        );
        $elements = $this->find('all', $params);
        foreach ($elements as $i => $element) {
            $elements[$i] = $elements[$i]['GalaxyElement'];
            unset($elements[$i]['GalaxyCluster']);
            unset($elements[$i]['GalaxyElement']);
        }
        return $elements;
    }