CVE-2019-9482 (published 2019-03-01T05:29Z)

In MISP 2.4.102, an authenticated user can view sightings that they should not be eligible for. Exploiting this requires access to the event that has received the sighting. The issue affects instances with restrictive sighting settings (event only / sighting reported only).

Severity: LOW
CVSS v2 base score: 3.5 (AV:N/AC:M/Au:S/C:P/I:N/A:N)
CVSS v3 base score: 5.3, MEDIUM (CVSS:3.0/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:N/A:N)

Weakness information:
cwe_id: CWE-862
cwe_name: Missing Authorization
description: The product does not perform an authorization check when an actor attempts to access a resource or perform an action.
extended_description: 
            Assuming a user with a given identity, authorization is the process of determining whether that user can access a given resource, based on the user's privileges and any permissions or other access-control specifications that apply to the resource.
            When access control checks are not applied, users are able to access data or perform actions that they should not be allowed to perform. This can lead to a wide range of problems, including information exposures, denial of service, and arbitrary code execution.
         
         

Fix information:
repo_url: https://github.com/MISP/MISP
commit_details: repo_url: https://github.com/MISP/MISP
author: iglocska
author_date: 2019-02-28 20:27:36+01:00
msg: fix: [vulnerability] Fixes a vulnerability where a user can view sightings that they should not be eligible for

- requires access to the event that has received the sighting
- affects instances with restrictive sighting settings (event only / sighting reported only)

- as reported by Tyler McLellan of CanCyber.org
repository: repo_url: https://github.com/MISP/MISP
repo_name: MISP/MISP
description: MISP (core software) - Open Source Threat Intelligence and Sharing Platform
repo_language: PHP
owner: MISP
file_changes: filename: SightingsController.php
change_type: ModificationType.MODIFY
diff: @@ -341,22 +341,72 @@ class SightingsController extends AppController
             'contain' => array('Organisation.name'),
             'order' => array('Sighting.date_sighting DESC')
         ));
+        if (!empty($sightings) && empty(Configure::read('Plugin.Sightings_policy')) && !$this->_isSiteAdmin()) {
+            $eventOwnerOrgIdList = array();
+            foreach ($sightings as $k => $sighting) {
+                if (empty($eventOwnerOrgIdList[$sighting['Sighting']['event_id']])) {
+                    $temp_event = $this->Event->find('first', array(
+                        'recursive' => -1,
+                        'conditions' => array('Event.id' => $sighting['Sighting']['event_id']),
+                        'fields' => array('Event.id', 'Event.orgc_id')
+                    ));
+                    $eventOwnerOrgIdList[$temp_event['Event']['id']] = $temp_event['Event']['orgc_id'];
+                }
+                if (empty($eventOwnerOrgIdList[$sighting['Sighting']['event_id']]) || $eventOwnerOrgIdList[$sighting['Sighting']['event_id']] !== $this->Auth->user('org_id')) {
+                    unset($sightings[$k]);
+                }
+            }
+            $sightings = array_values($sightings);
+        } else if (!empty($sightings) && Configure::read('Plugin.Sightings_policy') == 1 && !$this->_isSiteAdmin()) {
+            $eventsWithOwnSightings = array();
+            foreach ($sightings as $k => $sighting) {
+                if (empty($eventsWithOwnSightings[$sighting['Sighting']['event_id']])) {
+                    $eventsWithOwnSightings[$sighting['Sighting']['event_id']] = false;
+                    $sighting_temp = $this->Sighting->find('first', array(
+                        'recursive' => -1,
+                        'conditions' => array(
+                            'Sighting.event_id' => $sighting['Sighting']['event_id'],
+                            'Sighting.org_id' => $this->Auth->user('org_id')
+                        )
+                    ));
+                    if (empty($sighting_temp)) {
+                        $temp_event = $this->Event->find('first', array(
+                            'recursive' => -1,
+                            'conditions' => array(
+                                'Event.id' => $sighting['Sighting']['event_id'],
+                                'Event.orgc_id' => $this->Auth->user('org_id')
+                            ),
+                            'fields' => array('Event.id', 'Event.orgc_id')
+                        ));
+                        $eventsWithOwnSightings[$sighting['Sighting']['event_id']] = !empty($temp_event);
+                    } else {
+                        $eventsWithOwnSightings[$sighting['Sighting']['event_id']] = true;
+                    }
+                }
+                if (!$eventsWithOwnSightings[$sighting['Sighting']['event_id']]) {
+                    unset($sightings[$k]);
+                }
+            }
+            $sightings = array_values($sightings);
+        }
         $this->set('org_id', $org_id);
         $this->set('rawId', $rawId);
         $this->set('context', $context);
         $this->set('types', array('Sighting', 'False-positive', 'Expiration'));
         if (Configure::read('Plugin.Sightings_anonymise') && !$this->_isSiteAdmin()) {
-            foreach ($sightings as $k => $v) {
-                if ($v['Sighting']['org_id'] != $this->Auth->user('org_id')) {
-                    $sightings[$k]['Organisation']['name'] = '';
-                    $sightings[$k]['Sighting']['org_id'] = 0;
+            if (!empty($sightings)) {
+                foreach ($sightings as $k => $v) {
+                    if ($v['Sighting']['org_id'] != $this->Auth->user('org_id')) {
+                        $sightings[$k]['Organisation']['name'] = '';
+                        $sightings[$k]['Sighting']['org_id'] = 0;
+                    }
                 }
             }
         }
         if ($this->_isRest()) {
             return $this->RestResponse->viewData($sightings, $this->response->type());
         }
-        $this->set('sightings', $sightings);
+        $this->set('sightings', empty($sightings) ? array() : $sightings);
         $this->layout = false;
         $this->render('ajax/list_sightings');
     }

programming_language: PHP