CVE-2019-9482 (PHP, published 2019-03-01T05:29Z)
Description: value: 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 v3 base score: 5.3)
Weakness: CWE-862 \u2014 Missing Authorization
The product does not perform an authorization check when an actor attempts to access a resource or perform an action.
Repository: https://github.com/MISP/MISP
Files changed:
app/Controller/SightingsController.php
Commit message: 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


Vulnerable code:
            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;
        $this->set('sightings', $sightings);

Fixed code:
        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);
        }
            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;
                    }
        $this->set('sightings', empty($sightings) ? array() : $sightings);