CVE-2021-43835 (published 2021-12-15T20:15Z)

Sulu is an open-source PHP content management system based on the Symfony framework. In affected versions Sulu users who have access to any subset of the admin UI are able to elevate their privilege. Over the API it was possible for them to give themselves permissions to areas which they did not already had. This issue was introduced in 2.0.0-RC1 with the new ProfileController putAction. The versions have been patched in 2.2.18, 2.3.8 and 2.4.0. For users unable to upgrade the only known workaround is to apply a patch to the ProfileController manually.

Severity: MEDIUM
CVSS v2 base score: 6.5 (AV:N/AC:L/Au:S/C:P/I:P/A:P)
CVSS v3 base score: 7.2, HIGH (CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-269
cwe_name: Improper Privilege Management
description: The product does not properly assign, modify, track, or check privileges for an actor, creating an unintended sphere of control for that actor.
extended_description: 
            
         
         

Fix information:
repo_url: https://github.com/sulu/sulu
commit_details: repo_url: https://github.com/sulu/sulu
author: Alexander Schranz
author_date: 2021-12-15 14:49:33+01:00
msg: Merge pull request from GHSA-84px-q68r-2fc9
repository: repo_url: https://github.com/sulu/sulu
repo_name: sulu/sulu
description: Core framework that implements the functionality of the Sulu content management system
repo_language: PHP
owner: sulu
file_changes: filename: ProfileController.php
change_type: ModificationType.MODIFY
diff: @@ -118,7 +118,7 @@ class ProfileController implements ClassResourceInterface
     {
         $this->checkArguments($request);
         $user = $this->tokenStorage->getToken()->getUser();
-        $this->userManager->save($request->request->all(), $request->get('locale'), $user->getId(), true);
+        $this->userManager->save($this->getData($request), $request->get('locale'), $user->getId(), true);
 
         $user->setFirstName($request->get('firstName'));
         $user->setLastName($request->get('lastName'));
@@ -231,4 +231,20 @@ class ProfileController implements ClassResourceInterface
             throw new MissingArgumentException($this->userClass, 'locale');
         }
     }
+
+    /**
+     * @return array<string, mixed>
+     */
+    protected function getData(Request $request): array
+    {
+        $data = [];
+
+        foreach ($request->request->all() as $key => $value) {
+            if (\in_array($key, ['firstName', 'lastName', 'username', 'email', 'password', 'locale'], true)) {
+                $data[$key] = $value;
+            }
+        }
+
+        return $data;
+    }
 }

programming_language: PHP
filename: ProfileControllerTest.php
change_type: ModificationType.MODIFY
diff: @@ -87,6 +87,30 @@ class ProfileControllerTest extends SuluTestCase
         $this->assertEquals('de', $response->locale);
     }
 
+    public function testPutInvalidField()
+    {
+        $this->client->jsonRequest(
+            'PUT',
+            '/api/profile',
+            [
+                'firstName' => 'Hans',
+                'lastName' => 'Mustermann',
+                'username' => 'hansi',
+                'email' => 'hans.mustermann@muster.at',
+                'password' => 'testpassword',
+                'locale' => 'de',
+            ]
+        );
+
+        $response = \json_decode($this->client->getResponse()->getContent());
+        $this->assertHttpStatusCode(200, $this->client->getResponse());
+        $this->assertEquals('Hans', $response->firstName);
+        $this->assertEquals('Mustermann', $response->lastName);
+        $this->assertEquals('hansi', $response->username);
+        $this->assertEquals('hans.mustermann@muster.at', $response->email);
+        $this->assertEquals('de', $response->locale);
+    }
+
     public function testPutEmailNotUnique()
     {
         $existingContact = new Contact();

programming_language: PHP