CVE-2023-4381: Other (NVD-CWE-Other)
value: Unverified Password Change in GitHub repository instantsoft/icms2 prior to 2.16.1-git.
CWE description: NVD is only using a subset of CWE for mapping instead of the entire CWE, and the weakness type is not covered by that subset.
CVSS v3 base score: 4.3
Published: 2023-08-16T12:15Z
Repository: https://github.com/instantsoft/icms2
Language: PHP
Files changed: system/controllers/users/forms/form_password.php, system/languages/en/language.php, system/languages/ru/language.php
Commit date: 2023-08-16 14:00:16 +0300
Commit message: New password cannot be the same as the old password
Diff: diff --git a/system/controllers/users/forms/form_password.php b/system/controllers/users/forms/form_password.php
index b57c94a43..628bbd269 100755
--- a/system/controllers/users/forms/form_password.php
+++ b/system/controllers/users/forms/form_password.php
@@ -2,57 +2,69 @@
 
 class formUsersPassword extends cmsForm {
 
     public function init($profile) {
 
-        return array(
-
-            'basic' => array(
-                'type' => 'fieldset',
-                'title' => LANG_PASSWORD,
-                'childs' => array(
-                    new fieldString('password', array(
-                        'title' => LANG_OLD_PASS,
+        return [
+            'basic' => [
+                'type'   => 'fieldset',
+                'title'  => LANG_PASSWORD,
+                'childs' => [
+                    new fieldString('password', [
+                        'title'       => LANG_OLD_PASS,
                         'is_password' => true,
-                        'options'=>array(
-                            'min_length'=> 6,
-                            'max_length'=> 72
-                        ),
-                        'rules' => array(
-                            array('required'),
-                            array(function($controller, $data, $value)use($profile){
+                        'options'     => [
+                            'min_length' => 6,
+                            'max_length' => 72
+                        ],
+                        'rules' => [
+                            ['required'],
+                            [function ($controller, $data, $value)use ($profile) {
 
                                 $user = cmsCore::getModel('users')->getUserByAuth($profile['email'], $value);
 
-                                if (!$user){
+                                if (!$user) {
                                     return LANG_OLD_PASS_INCORRECT;
                                 }
 
                                 return true;
-
-                            })
-                        )
-                    )),
-                    new fieldString('password1', array(
-                        'title' => LANG_NEW_PASS,
-                        'is_password' => true,
-                        'options'=>array(
-                            'min_length'=> 6,
-                            'max_length'=> 72
-                        )
-                    )),
-                    new fieldString('password2', array(
-                        'title' => LANG_RETYPE_NEW_PASS,
+                            }]
+                        ]
+                    ]),
+                    new fieldString('password1', [
+                        'title'       => LANG_NEW_PASS,
                         'is_password' => true,
-                        'options'=>array(
-                            'min_length'=> 6,
-                            'max_length'=> 72
-                        )
-                    ))
-                )
-            )
+                        'options'     => [
+                            'min_length' => 6,
+                            'max_length' => 72
+                        ],
+                        'rules' => [
+                            [function ($controller, $data, $value)use ($profile) {
 
-        );
+                                if (!$value) {
+                                    return true;
+                                }
 
-    }
+                                $user = cmsCore::getModel('users')->getUserByAuth($profile['email'], $value);
 
+                                if ($user) {
+                                    return ERR_NEW_PASS_AS_OLD;
+                                }
+
+                                return true;
+                            }]
+                        ]
+                    ]),
+                    new fieldString('password2', [
+                        'title'       => LANG_RETYPE_NEW_PASS,
+                        'is_password' => true,
+                        'options'     => [
+                            'min_length' => 6,
+                            'max_length' => 72
+                        ]
+                    ])
+                ]
+            ]
+        ];
+
+    }
 }
diff --git a/system/languages/en/language.php b/system/languages/en/language.php
index 625ae30f1..cc95f2ed5 100755
--- a/system/languages/en/language.php
+++ b/system/languages/en/language.php
@@ -460,10 +460,11 @@
     define('ERR_REQ_EMAIL', 		 	 	 'E-mail is required!');
     define('ERR_EMPTY_FIELDS', 			 	 'All fields are required!');
     define('ERR_NICKNAME_EXISTS', 			 'Nickname &laquo;%s&raquo; is already used');
     define('ERR_WRONG_OLD_PASS', 		 	 'Password change error: Old password is incorrect');
     define('ERR_NEW_PASS_MISMATCH', 		 'Password change error: Passwords do not match');
+    define('ERR_NEW_PASS_AS_OLD', 		     'The new password cannot be the same as the old password');
     define('ERR_NEW_PASS_REQUIRED', 		 'Enter your new password twice!');
 
     //CAPTCHA
     define('LANG_CAPTCHA_CODE', 		 	 'Spam protection');
     define('LANG_CAPTCHA_ERROR', 		 	 'Spam protection code is incorrect');
diff --git a/system/languages/ru/language.php b/system/languages/ru/language.php
index dedce06c6..df75b529c 100755
--- a/system/languages/ru/language.php
+++ b/system/languages/ru/language.php
@@ -459,10 +459,11 @@
     define('ERR_REQ_EMAIL', 		 	 	 'Необходимо указать e-mail!');
     define('ERR_EMPTY_FIELDS', 			 	 'Обнаружены пустые поля!');
     define('ERR_NICKNAME_EXISTS', 			 'Никнейм &laquo;%s&raquo; занят');
     define('ERR_WRONG_OLD_PASS', 		 	 'Ошибка изменения пароля: Старый пароль указан неверно');
     define('ERR_NEW_PASS_MISMATCH', 		 'Ошибка изменения пароля: Пароли не совпали');
+    define('ERR_NEW_PASS_AS_OLD', 		     'Новый пароль не может быть таким же, как старый');
     define('ERR_NEW_PASS_REQUIRED', 		 'Нужно указать новый пароль дважды!');
 
     //CAPTCHA
     define('LANG_CAPTCHA_CODE', 		 	 'Защита от спама');
     define('LANG_CAPTCHA_ERROR', 		 	 'Неправильно указан код защиты от спама');

Vulnerable code:         return array(

            'basic' => array(
                'type' => 'fieldset',
                'title' => LANG_PASSWORD,
                'childs' => array(
                    new fieldString('password', array(
                        'title' => LANG_OLD_PASS,
                        'options'=>array(
                            'min_length'=> 6,
                            'max_length'=> 72
                        ),
                        'rules' => array(
                            array('required'),
                            array(function($controller, $data, $value)use($profile){
                                if (!$user){

                            })
                        )
                    )),
                    new fieldString('password1', array(
                        'title' => LANG_NEW_PASS,
                        'is_password' => true,
                        'options'=>array(
                            'min_length'=> 6,
                            'max_length'=> 72
                        )
                    )),
                    new fieldString('password2', array(
                        'title' => LANG_RETYPE_NEW_PASS,
                        'options'=>array(
                            'min_length'=> 6,
                            'max_length'=> 72
                        )
                    ))
                )
            )
        );
    }
Fixed code:         return [
            'basic' => [
                'type'   => 'fieldset',
                'title'  => LANG_PASSWORD,
                'childs' => [
                    new fieldString('password', [
                        'title'       => LANG_OLD_PASS,
                        'options'     => [
                            'min_length' => 6,
                            'max_length' => 72
                        ],
                        'rules' => [
                            ['required'],
                            [function ($controller, $data, $value)use ($profile) {
                                if (!$user) {
                            }]
                        ]
                    ]),
                    new fieldString('password1', [
                        'title'       => LANG_NEW_PASS,
                        'options'     => [
                            'min_length' => 6,
                            'max_length' => 72
                        ],
                        'rules' => [
                            [function ($controller, $data, $value)use ($profile) {
                                if (!$value) {
                                    return true;
                                }
                                $user = cmsCore::getModel('users')->getUserByAuth($profile['email'], $value);
                                if ($user) {
                                    return ERR_NEW_PASS_AS_OLD;
                                }

                                return true;
                            }]
                        ]
                    ]),
                    new fieldString('password2', [
                        'title'       => LANG_RETYPE_NEW_PASS,
                        'is_password' => true,
                        'options'     => [
                            'min_length' => 6,
                            'max_length' => 72
                        ]
                    ])
                ]
            ]
        ];

    }
    define('ERR_NEW_PASS_AS_OLD', 		     'The new password cannot be the same as the old password');
    define('ERR_NEW_PASS_AS_OLD', 		     'Новый пароль не может быть таким же, как старый');