CVE-2021-31780: Improper Removal of Sensitive Information Before Storage or Transfer (CWE-212)
value: In app/Model/MispObject.php in MISP 2.4.141, an incorrect sharing group association could lead to information disclosure on an event edit. When an object has a sharing group associated with an event edit, the sharing group object is ignored and instead the passed local ID is reused.
CWE description: The product stores, transfers, or shares a resource that contains sensitive information, but it does not properly remove that information before the product makes the resource available to unauthorized actors.
CVSS v3 base score: 7.5
Published: 2021-04-23T20:15Z
Repository: https://github.com/MISP/MISP
Language: PHP
Files changed: app/Model/MispObject.php
Commit date: 2021-04-08 10:57:20 +0200
Commit message: fix: [security] Sharing group misassociation on sync

- when an object has a sharing group associated on an event edit, the sharing group object is ignored and instead the passed local ID is reused
- as reported by Jeroen Pinoy

Diff: diff --git a/app/Model/MispObject.php b/app/Model/MispObject.php
index 37511195700..7bcbc208678 100644
--- a/app/Model/MispObject.php
+++ b/app/Model/MispObject.php
@@ -962,10 +962,35 @@ class MispObject extends AppModel
     }
 
     public function editObject($object, $eventId, $user, $log, $force = false, &$nothingToChange = false)
     {
         $object['event_id'] = $eventId;
+        if (isset($object['distribution']) && $object['distribution'] == 4) {
+            if (!empty($object['SharingGroup'])) {
+                $object['sharing_group_id'] = $this->SharingGroup->captureSG($object['SharingGroup'], $user);
+            } elseif (!empty($object['sharing_group_id'])) {
+                if (!$this->SharingGroup->checkIfAuthorised($user, $object['sharing_group_id'])) {
+                    unset($object['sharing_group_id']);
+                }
+            }
+            if (empty($object['sharing_group_id'])) {
+                $object_short = (isset($object['meta-category']) ? $object['meta-category'] : 'N/A') . '/' . (isset($object['name']) ? $object['name'] : 'N/A') . ' ' . (isset($object['uuid']) ? $object['uuid'] : 'N/A');
+                $this->Log = ClassRegistry::init('Log');
+                $this->Log->create();
+                $this->Log->save(array(
+                    'org' => $user['Organisation']['name'],
+                    'model' => 'MispObject',
+                    'model_id' => 0,
+                    'email' => $user['email'],
+                    'action' => 'edit',
+                    'user_id' => $user['id'],
+                    'title' => 'Object dropped due to invalid sharing group for Event ' . $eventId . ' failed: ' . $object_short,
+                    'change' => 'Validation errors: ' . json_encode($this->validationErrors) . ' Full Object: ' . json_encode($object),
+                ));
+                return 'Invalid sharing group choice.';
+            }
+        }
         if (isset($object['uuid'])) {
             $existingObject = $this->find('first', array(
                 'recursive' => -1,
                 'conditions' => array('Object.uuid' => $object['uuid'])
             ));
@@ -974,11 +999,11 @@ class MispObject extends AppModel
             } else {
                 if ($existingObject['Object']['event_id'] != $eventId) {
                     $log->create();
                     $log->save(array(
                             'org' => $user['Organisation']['name'],
-                            'model' => 'Object',
+                            'model' => 'MispObject',
                             'model_id' => 0,
                             'email' => $user['email'],
                             'action' => 'edit',
                             'user_id' => $user['id'],
                             'title' => 'Duplicate UUID found in object',

Vulnerable code:                             'model' => 'Object',
Fixed code:         if (isset($object['distribution']) && $object['distribution'] == 4) {
            if (!empty($object['SharingGroup'])) {
                $object['sharing_group_id'] = $this->SharingGroup->captureSG($object['SharingGroup'], $user);
            } elseif (!empty($object['sharing_group_id'])) {
                if (!$this->SharingGroup->checkIfAuthorised($user, $object['sharing_group_id'])) {
                    unset($object['sharing_group_id']);
                }
            }
            if (empty($object['sharing_group_id'])) {
                $object_short = (isset($object['meta-category']) ? $object['meta-category'] : 'N/A') . '/' . (isset($object['name']) ? $object['name'] : 'N/A') . ' ' . (isset($object['uuid']) ? $object['uuid'] : 'N/A');
                $this->Log = ClassRegistry::init('Log');
                $this->Log->create();
                $this->Log->save(array(
                    'org' => $user['Organisation']['name'],
                    'model' => 'MispObject',
                    'model_id' => 0,
                    'email' => $user['email'],
                    'action' => 'edit',
                    'user_id' => $user['id'],
                    'title' => 'Object dropped due to invalid sharing group for Event ' . $eventId . ' failed: ' . $object_short,
                    'change' => 'Validation errors: ' . json_encode($this->validationErrors) . ' Full Object: ' . json_encode($object),
                ));
                return 'Invalid sharing group choice.';
            }
        }
                            'model' => 'MispObject',