瀏覽代碼

Try to fix the email leak in password recovery form

https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html
Visman 4 年之前
父節點
當前提交
019e997fd5
共有 3 個文件被更改,包括 59 次插入51 次删除
  1. 57 49
      app/Models/Pages/Auth.php
  2. 1 1
      app/lang/en/auth.po
  3. 1 1
      app/lang/ru/auth.po

+ 57 - 49
app/Models/Pages/Auth.php

@@ -213,19 +213,16 @@ class Auth extends Page
         $v = null;
         $v = null;
 
 
         if ('POST' === $method) {
         if ('POST' === $method) {
-            $tmpUser = $this->c->users->create();
-
             $v = $this->c->Validator->reset()
             $v = $this->c->Validator->reset()
                 ->addValidators([
                 ->addValidators([
                 ])->addRules([
                 ])->addRules([
                     'token'  => 'token:Forget',
                     'token'  => 'token:Forget',
-                    'email'  => 'required|string:trim|email:noban,exists,flood',
+                    'email'  => 'required|string:trim|email',
                     'submit' => 'required|string',
                     'submit' => 'required|string',
                 ])->addAliases([
                 ])->addAliases([
                 ])->addMessages([
                 ])->addMessages([
                     'email.email' => 'Invalid email',
                     'email.email' => 'Invalid email',
                 ])->addArguments([
                 ])->addArguments([
-                    'email.email' => $tmpUser, // сюда идет возрат данных по найденному пользователю
                 ]);
                 ]);
 
 
             $v       = $this->c->Test->beforeValidation($v);
             $v       = $this->c->Test->beforeValidation($v);
@@ -237,59 +234,70 @@ class Auth extends Page
             ];
             ];
 
 
             if ($isValid) {
             if ($isValid) {
-                $key  = $this->c->Secury->randomPass(32);
-                $hash = $this->c->Secury->hash($tmpUser->id . $key);
-                $link = $this->c->Router->link(
-                    'ChangePassword',
-                    [
-                        'id'   => $tmpUser->id,
-                        'key'  => $key,
-                        'hash' => $hash,
-                    ]
-                );
-                $tplData = [
-                    'fRootLink' => $this->c->Router->link('Index'),
-                    'fMailer'   => __('Mailer', $this->c->config->o_board_title),
-                    'username'  => $tmpUser->username,
-                    'link'      => $link,
-                ];
-
-                try {
-                    $isSent = $this->c->Mail
-                        ->reset()
-                        ->setMaxRecipients(1)
-                        ->setFolder($this->c->DIR_LANG)
-                        ->setLanguage($tmpUser->language)
-                        ->setTo($tmpUser->email, $tmpUser->username)
-                        ->setFrom($this->c->config->o_webmaster_email, $tplData['fMailer'])
-                        ->setTpl('passphrase_reset.tpl', $tplData)
-                        ->send();
-                } catch (MailException $e) {
-                    $isSent = false;
-
-                    $this->c->Log->error('Passphrase reset: form, MailException', [
-                        'exception' => $e,
-                        'headers'   => false,
-                    ]);
-                }
+                $tmpUser = $this->c->users->create();
 
 
-                if ($isSent) {
-                    $tmpUser->activate_string = $key;
-                    $tmpUser->last_email_sent = \time();
-
-                    $this->c->users->update($tmpUser);
-
-                    $this->c->Log->info('Passphrase reset: form, ok', $context);
+                $v = $this->c->Validator->reset()
+                    ->addRules([
+                        'email' => 'required|string:trim|email:noban,exists,flood',
+                    ])->addArguments([
+                        'email.email' => $tmpUser, // сюда идет возрат данных по найденному пользователю
+                    ]);
 
 
-                    return $this->c->Message->message(__('Forget mail', $this->c->config->o_admin_email), false, 200);
+                if ($v->validation($_POST)) {
+                    $key  = $this->c->Secury->randomPass(32);
+                    $hash = $this->c->Secury->hash($tmpUser->id . $key);
+                    $link = $this->c->Router->link(
+                        'ChangePassword',
+                        [
+                            'id'   => $tmpUser->id,
+                            'key'  => $key,
+                            'hash' => $hash,
+                        ]
+                    );
+                    $tplData = [
+                        'fRootLink' => $this->c->Router->link('Index'),
+                        'fMailer'   => __('Mailer', $this->c->config->o_board_title),
+                        'username'  => $tmpUser->username,
+                        'link'      => $link,
+                    ];
+
+                    try {
+                        $isSent = $this->c->Mail
+                            ->reset()
+                            ->setMaxRecipients(1)
+                            ->setFolder($this->c->DIR_LANG)
+                            ->setLanguage($tmpUser->language)
+                            ->setTo($tmpUser->email, $tmpUser->username)
+                            ->setFrom($this->c->config->o_webmaster_email, $tplData['fMailer'])
+                            ->setTpl('passphrase_reset.tpl', $tplData)
+                            ->send();
+                    } catch (MailException $e) {
+                        $isSent = false;
+
+                        $this->c->Log->error('Passphrase reset: email form, MailException', [
+                            'exception' => $e,
+                            'headers'   => false,
+                        ]);
+                    }
+
+                    if ($isSent) {
+                        $tmpUser->activate_string = $key;
+                        $tmpUser->last_email_sent = \time();
+
+                        $this->c->users->update($tmpUser);
+
+                        $this->c->Log->info('Passphrase reset: email form, ok', $context);
+                    }
                 } else {
                 } else {
-                    return $this->c->Message->message(__('Error mail', $this->c->config->o_admin_email), true, 424);
+                    $this->c->Log->warning('Passphrase reset: email form, fail', $context);
                 }
                 }
+
+                return $this->c->Message->message(__('Forget mail', $this->c->config->o_admin_email), false, 200);
             }
             }
 
 
             $this->fIswev = $v->getErrors();
             $this->fIswev = $v->getErrors();
 
 
-            $this->c->Log->warning('Passphrase reset: form, fail', $context);
+            $this->c->Log->warning('Passphrase reset: email form, fail', $context);
         }
         }
 
 
         $this->hhsLevel   = 'secure';
         $this->hhsLevel   = 'secure';

+ 1 - 1
app/lang/en/auth.po

@@ -43,7 +43,7 @@ msgid "Remember me"
 msgstr "Remember me"
 msgstr "Remember me"
 
 
 msgid "Forget mail"
 msgid "Forget mail"
-msgstr "An email has been sent to the specified address with instructions on how to change your passphrase. If it does not arrive you can contact the forum administrator at <a href=\"mailto:%1$s\">%1$s</a>."
+msgstr "If the email you specified is in the database, then an email will be sent to it with instructions on how to change the passphrase. If it does not arrive you can contact the forum administrator at <a href=\"mailto:%1$s\">%1$s</a>."
 
 
 msgid "Pass not match"
 msgid "Pass not match"
 msgstr "Passphrases do not match."
 msgstr "Passphrases do not match."

+ 1 - 1
app/lang/ru/auth.po

@@ -43,7 +43,7 @@ msgid "Remember me"
 msgstr "Запомнить меня"
 msgstr "Запомнить меня"
 
 
 msgid "Forget mail"
 msgid "Forget mail"
-msgstr "Письмо с инструкцией по изменению кодовой фразы было выслано на указанный вами почтовый адрес. Если вы не получите его, свяжитесь с администрацией форума по адресу <a href=\"mailto:%1$s\">%1$s</a>."
+msgstr "Если указанный вами почтовый адрес есть в базе данных, то на него будет отправлено письмо с инструкцией по изменению кодовой фразы. Если вы его не получите, то свяжитесь с администрацией форума по адресу <a href=\"mailto:%1$s\">%1$s</a>."
 
 
 msgid "Pass not match"
 msgid "Pass not match"
 msgstr "Кодовые фразы не совпадают."
 msgstr "Кодовые фразы не совпадают."