CVE-2024-36119: Insufficient Information (NVD-CWE-noinfo)
value: Statamic is a, Laravel + Git powered CMS designed for building websites. In affected versions users registering via the `user:register_form` tag will have their password confirmation stored in plain text in their user file. This only affects sites matching **all** of the following conditions: 1. Running Statamic versions between 5.3.0 and 5.6.1. (This version range represents only one calendar week), 2. Using the `user:register_form` tag. 3. Using file-based user accounts. (Does not affect users stored in a database.), 4. Has users that have registered during that time period. (Existing users are not affected.). Additionally passwords are only visible to users that have access to read user yaml files, typically developers of the application itself. This issue has been patched in version 5.6.2, however any users registered during that time period and using the affected version range will still have the the `password_confirmation` value in their yaml files. We recommend that affected users have their password reset. System administrators are advised to upgrade their deployments. There are no known workarounds for this vulnerability. Anyone who commits their files to a public git repo, may consider clearing the sensitive data from the git history as it is likely that passwords were uploaded.
CWE description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
Published: 2024-05-30T21:15Z
Repository: https://github.com/statamic/cms
Language: PHP
Files changed: src/Http/Requests/UserRegisterRequest.php, tests/Tags/User/RegisterFormTest.php
Commit date: 2024-05-30 10:36:04 -0400
Commit message: [5.x] Prevent user registration form saving `password_confirmation` (#10228)

Co-authored-by: Duncan McClean <duncan@duncanmcclean.com>

Diff: diff --git a/src/Http/Requests/UserRegisterRequest.php b/src/Http/Requests/UserRegisterRequest.php
index d7bc535d21..bbf9ff3572 100644
--- a/src/Http/Requests/UserRegisterRequest.php
+++ b/src/Http/Requests/UserRegisterRequest.php
@@ -50,11 +50,11 @@ class UserRegisterRequest extends FormRequest
 
     public function processedValues()
     {
         return $this->blueprintFields->process()->values()
             ->only(array_keys($this->submittedValues))
-            ->except(['email', 'groups', 'roles', 'super']);
+            ->except(['email', 'groups', 'roles', 'super', 'password_confirmation']);
     }
 
     public function validator()
     {
         $blueprint = User::blueprint();
diff --git a/tests/Tags/User/RegisterFormTest.php b/tests/Tags/User/RegisterFormTest.php
index eead21e10a..2097688ed2 100644
--- a/tests/Tags/User/RegisterFormTest.php
+++ b/tests/Tags/User/RegisterFormTest.php
@@ -2,11 +2,13 @@
 
 namespace Tests\Tags\User;
 
 use Statamic\Facades\Blueprint;
 use Statamic\Facades\Parse;
+use Statamic\Facades\Role;
 use Statamic\Facades\User;
+use Statamic\Facades\UserGroup;
 use Statamic\Statamic;
 use Tests\NormalizesHtml;
 use Tests\PreventSavingStacheItemsToDisk;
 use Tests\TestCase;
 
@@ -337,10 +339,39 @@ EOT
 
         $this->assertStringContainsString($expectedRedirect, $output);
         $this->assertStringContainsString($expectedErrorRedirect, $output);
     }
 
+    /** @test */
+    public function it_ensures_some_fields_arent_saved()
+    {
+        UserGroup::make('client')->title('Client')->save();
+        Role::make('admin')->title('Admin')->save();
+
+        $this->assertNull(User::findByEmail('san@holo.com'));
+        $this->assertFalse(auth()->check());
+
+        $this
+            ->post('/!/auth/register', [
+                'email' => 'san@holo.com',
+                'password' => 'chewbacca',
+                'password_confirmation' => 'chewbacca',
+                'groups' => ['client'],
+                'roles' => ['admin'],
+                'super' => true,
+            ])
+            ->assertSessionHasNoErrors()
+            ->assertLocation('/');
+
+        $user = User::findByEmail('san@holo.com');
+
+        $this->assertEquals($user->groups()->count(), 0);
+        $this->assertEquals($user->roles()->count(), 0);
+        $this->assertNull($user->get('super'));
+        $this->assertNull($user->get('password_confirmation'));
+    }
+
     private function useCustomBlueprint()
     {
         $blueprint = Blueprint::make()->setContents([
             'fields' => [
                 [

Vulnerable code:             ->except(['email', 'groups', 'roles', 'super']);
Fixed code:             ->except(['email', 'groups', 'roles', 'super', 'password_confirmation']);
use Statamic\Facades\Role;
use Statamic\Facades\UserGroup;
    /** @test */
    public function it_ensures_some_fields_arent_saved()
    {
        UserGroup::make('client')->title('Client')->save();
        Role::make('admin')->title('Admin')->save();

        $this->assertNull(User::findByEmail('san@holo.com'));
        $this->assertFalse(auth()->check());

        $this
            ->post('/!/auth/register', [
                'email' => 'san@holo.com',
                'password' => 'chewbacca',
                'password_confirmation' => 'chewbacca',
                'groups' => ['client'],
                'roles' => ['admin'],
                'super' => true,
            ])
            ->assertSessionHasNoErrors()
            ->assertLocation('/');

        $user = User::findByEmail('san@holo.com');

        $this->assertEquals($user->groups()->count(), 0);
        $this->assertEquals($user->roles()->count(), 0);
        $this->assertNull($user->get('super'));
        $this->assertNull($user->get('password_confirmation'));
    }