CVE-2024-25674: Unrestricted Upload of File with Dangerous Type (CWE-434)
value: An issue was discovered in MISP before 2.4.184. Organisation logo upload is insecure because of a lack of checks for the file extension and MIME type.
CWE description: The product allows the upload or transfer of dangerous file types that are automatically processed within its environment.
CVSS v3 base score: 9.8
Published: 2024-02-09T09:15Z
Repository: https://github.com/MISP/MISP
Language: PHP
Files changed: app/Controller/OrganisationsController.php
Commit date: 2024-01-31 14:27:59 +0100
Commit message: fix: [security] Improved security checks for organisation logo upload

- As reported by Andrei Agape / Teliacompany

Checks are:
- Maximum file size of 250K since the recommanded picture size is 48x48.
- File extension check
- File mime type checks

Diff: diff --git a/app/Controller/OrganisationsController.php b/app/Controller/OrganisationsController.php
index 45ea69bf3d1..0b400286ef6 100644
--- a/app/Controller/OrganisationsController.php
+++ b/app/Controller/OrganisationsController.php
@@ -479,10 +479,29 @@ class OrganisationsController extends AppController
         $logo = $this->request->data['Organisation']['logo'];
         if ($logo['size'] > 0 && $logo['error'] == 0) {
             $extension = pathinfo($logo['name'], PATHINFO_EXTENSION);
             $filename = $orgId . '.' . ($extension === 'svg' ? 'svg' : 'png');
 
+            if ($logo['size'] > 250*1024) {
+                $this->Flash->error(__('This organisation logo is too large, maximum file size allowed is 250kB.'));
+                return false;
+            }
+
+            if ($extension !== 'svg' && $extension !== 'png') {
+                $this->Flash->error(__('Invalid file extension, Only PNG and SVG images are allowed.'));
+                return false;
+            }
+
+            $imgMime = mime_content_type($logo['tmp_name']);
+            if ($extension === 'png' && !exif_imagetype($logo['tmp_name'])) {
+                $this->Flash->error(__('This is not a valid PNG image.'));
+                return false;
+            } else if ($extension === 'svg' && !($imgMime === 'image/svg+xml' || $imgMime === 'image/svg')) {
+                $this->Flash->error(__('This is not a valid SVG image.'));
+                return false;
+            }
+
             if ($extension === 'svg' && !Configure::read('Security.enable_svg_logos')) {
                 $this->Flash->error(__('Invalid file extension, SVG images are not allowed.'));
                 return false;
             }
 

Fixed code:             if ($logo['size'] > 250*1024) {
                $this->Flash->error(__('This organisation logo is too large, maximum file size allowed is 250kB.'));
                return false;
            }

            if ($extension !== 'svg' && $extension !== 'png') {
                $this->Flash->error(__('Invalid file extension, Only PNG and SVG images are allowed.'));
                return false;
            }

            $imgMime = mime_content_type($logo['tmp_name']);
            if ($extension === 'png' && !exif_imagetype($logo['tmp_name'])) {
                $this->Flash->error(__('This is not a valid PNG image.'));
                return false;
            } else if ($extension === 'svg' && !($imgMime === 'image/svg+xml' || $imgMime === 'image/svg')) {
                $this->Flash->error(__('This is not a valid SVG image.'));
                return false;
            }