CVE-2023-23937 (published 2023-02-03T20:15Z)

Pimcore is an Open Source Data & Experience Management Platform: PIM, MDM, CDP, DAM, DXP/CMS & Digital Commerce.\nThe upload functionality for updating user profile does not properly validate the file content-type, allowing any authenticated user to bypass this security check by adding a valid signature (p.e. GIF89) and sending any invalid content-type. This could allow an authenticated attacker to upload HTML files with JS content that will be executed in the context of the domain. This issue has been patched in version 10.5.16. 

CVSS v3 base score: 5.4, MEDIUM (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N)

Weakness information:
cwe_id: CWE-434
cwe_name: Unrestricted Upload of File with Dangerous Type
description: The product allows the upload or transfer of dangerous file types that are automatically processed within its environment.
extended_description: 
            
            
            
            
            
         
         

Fix information:
repo_url: https://github.com/pimcore/pimcore
commit_details: repo_url: https://github.com/pimcore/pimcore
author: JiaJia Ji
author_date: 2023-02-01 07:32:58+01:00
msg: [Task]: Mime type check on Profile Avatar upload (#14125)

* Task: mime type check on avatar upload

* Task: change to use getTypeFromMimeMapping

* Task: add missing import
repository: repo_url: https://github.com/pimcore/pimcore
repo_name: pimcore/pimcore
description: Core Framework for the Open Source Data & Experience Management Platform (PIM, MDM, CDP, DAM, DXP/CMS & Digital Commerce)
repo_language: PHP
owner: pimcore
file_changes: filename: UserController.php
change_type: ModificationType.MODIFY
diff: @@ -21,12 +21,14 @@ use Pimcore\Bundle\AdminBundle\Controller\AdminController;
 use Pimcore\Bundle\AdminBundle\HttpFoundation\JsonResponse;
 use Pimcore\Controller\KernelControllerEventInterface;
 use Pimcore\Logger;
+use Pimcore\Model\Asset;
 use Pimcore\Model\DataObject;
 use Pimcore\Model\Element;
 use Pimcore\Model\User;
 use Pimcore\Tool;
 use Scheb\TwoFactorBundle\Security\TwoFactor\Provider\Google\GoogleAuthenticatorInterface;
 use Symfony\Component\HttpFoundation\BinaryFileResponse;
+use Symfony\Component\HttpFoundation\File\UploadedFile;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpFoundation\Response;
 use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBagInterface;
@@ -797,6 +799,15 @@ class UserController extends AdminController implements KernelControllerEventInt
             throw $this->createAccessDeniedHttpException('Only admin users are allowed to modify admin users');
         }
 
+        //Check if uploaded file is an image
+        $avatarFile = $request->files->get('Filedata');
+
+        $assetType = Asset::getTypeFromMimeMapping($avatarFile->getMimeType(), $avatarFile);
+
+        if (!$avatarFile instanceof UploadedFile || $assetType !== 'image') {
+            throw new \Exception('Unsupported file format.');
+        }
+
         $userObj->setImage($_FILES['Filedata']['tmp_name']);
 
         // set content-type to text/html, otherwise (when application/json is sent) chrome will complain in

programming_language: PHP
filename: panel.js
change_type: ModificationType.MODIFY
diff: @@ -250,6 +250,9 @@ pimcore.settings.profile.panel = Class.create({
                                 Ext.getCmp("pimcore_profile_delete_image_" + this.currentUser.id).setVisible(true);
                                 pimcore.helpers.reloadUserImage(this.currentUser.id);
                                 this.currentUser.hasImage = true;
+                            }.bind(this),
+                            function () {
+                                Ext.MessageBox.alert(t('error'), t("unsupported_filetype"));
                             }.bind(this)
                         );
                     }.bind(this)

programming_language: JavaScript
filename: settings.js
change_type: ModificationType.MODIFY
diff: @@ -177,6 +177,9 @@ pimcore.settings.user.user.settings = Class.create({
                                 Ext.getCmp("pimcore_user_delete_image_" + this.currentUser.id).setVisible(true);
                                 pimcore.helpers.reloadUserImage(this.currentUser.id);
                                 this.currentUser.hasImage = true;
+                            }.bind(this),
+                            function () {
+                                Ext.MessageBox.alert(t('error'), t("unsupported_filetype"));
                             }.bind(this)
                         );
                     }.bind(this)

programming_language: JavaScript