From 388f1adb594bbdf706cb892b6ecf15311aae1ed1 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Wed, 14 Jun 2023 14:54:59 -0600 Subject: [PATCH 1/3] typo --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bd230d5..b75d4a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ 1. [](#bugfix) * Sanitized `email` during the "forgot password" process to protect against XSS attacks - * Fixed an account enumeration vulneratiblity in forgot password [#293](https://github.com/getgrav/grav-plugin-login/pull/293) + * Fixed an account enumeration vulnerability in forgot password [#293](https://github.com/getgrav/grav-plugin-login/pull/293) # v3.7.4 ## 05/09/2023 From 964dfcba9c9b0505ba105d0ab1a7aac4ae0edf17 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Thu, 29 Jun 2023 13:30:03 -0600 Subject: [PATCH 2/3] Fixed issue with password reset creating empty user file for non-existent user --- CHANGELOG.md | 6 ++++ classes/Controller.php | 71 ++++++++++++++++++++++-------------------- 2 files changed, 44 insertions(+), 33 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b75d4a1..9ad848e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# v3.7.6 +## mm/dd/2023 + +1. [](#bugfix) + * Don't save an empty user file on password reset of non-existing user + # v3.7.5 ## 06/14/2023 diff --git a/classes/Controller.php b/classes/Controller.php index 9421cdd..ed006d7 100644 --- a/classes/Controller.php +++ b/classes/Controller.php @@ -347,61 +347,66 @@ protected function taskForgot() $config = $this->grav['config']; $data = $this->post; + /** @var Language $language */ + $language = $this->grav['language']; + $messages = $this->grav['messages']; + /** @var UserCollectionInterface $users */ $users = $this->grav['accounts']; - $email = $data['email'] ?? ''; // Sanitize $email $email = htmlspecialchars(strip_tags($email), ENT_QUOTES, 'UTF-8'); - $user = !empty($email) ? $users->find($email, ['email']) : null; - - /** @var Language $language */ - $language = $this->grav['language']; - $messages = $this->grav['messages']; + // Find user if they exist + $user = $users->find($email, ['email']); - if (!isset($this->grav['Email'])) { - $messages->add($language->translate('PLUGIN_LOGIN.FORGOT_EMAIL_NOT_CONFIGURED'), 'error'); - $this->setRedirect($this->login->getRoute('forgot') ?? '/'); + if ($user->exists()) { + if (!isset($this->grav['Email'])) { + $messages->add($language->translate('PLUGIN_LOGIN.FORGOT_EMAIL_NOT_CONFIGURED'), 'error'); + $this->setRedirect($this->login->getRoute('forgot') ?? '/'); - return true; - } + return true; + } - $from = $config->get('plugins.email.from'); + $from = $config->get('plugins.email.from'); - if (empty($from)) { - $messages->add($language->translate('PLUGIN_LOGIN.FORGOT_EMAIL_NOT_CONFIGURED'), 'error'); - $this->setRedirect($this->login->getRoute('forgot') ?? '/'); + if (empty($from)) { + $messages->add($language->translate('PLUGIN_LOGIN.FORGOT_EMAIL_NOT_CONFIGURED'), 'error'); + $this->setRedirect($this->login->getRoute('forgot') ?? '/'); - return true; - } + return true; + } - $userKey = $user->username; - $rateLimiter = $this->login->getRateLimiter('pw_resets'); - $rateLimiter->registerRateLimitedAction($userKey); + $userKey = $user->username; + $rateLimiter = $this->login->getRateLimiter('pw_resets'); + $rateLimiter->registerRateLimitedAction($userKey); - if ($rateLimiter->isRateLimited($userKey)) { - $messages->add($language->translate(['PLUGIN_LOGIN.FORGOT_CANNOT_RESET_IT_IS_BLOCKED', $email, $rateLimiter->getInterval()]), 'error'); - $this->setRedirect($this->login->getRoute('login') ?? '/'); + if ($rateLimiter->isRateLimited($userKey)) { + $messages->add($language->translate(['PLUGIN_LOGIN.FORGOT_CANNOT_RESET_IT_IS_BLOCKED', $email, $rateLimiter->getInterval()]), 'error'); + $this->setRedirect($this->login->getRoute('login') ?? '/'); - return true; - } + return true; + } - $token = md5(uniqid((string)mt_rand(), true)); - $expire = time() + 604800; // next week + $token = md5(uniqid((string)mt_rand(), true)); + $expire = time() + 604800; // next week - $user->reset = $token . '::' . $expire; - $user->save(); + $user->reset = $token . '::' . $expire; + $user->save(); - try { - Email::sendResetPasswordEmail($user); + try { + Email::sendResetPasswordEmail($user); + $messages->add($language->translate('PLUGIN_LOGIN.FORGOT_INSTRUCTIONS_SENT_VIA_EMAIL'), 'info'); + } catch (\Exception $e) { + $messages->add($language->translate('PLUGIN_LOGIN.FORGOT_FAILED_TO_EMAIL'), 'error'); + } + } else { $messages->add($language->translate('PLUGIN_LOGIN.FORGOT_INSTRUCTIONS_SENT_VIA_EMAIL'), 'info'); - } catch (\Exception $e) { - $messages->add($language->translate('PLUGIN_LOGIN.FORGOT_FAILED_TO_EMAIL'), 'error'); } + $this->setRedirect($this->login->getRoute('login') ?? '/'); return true; From d23aadea2d4eee4a1c3e62828b24d4b6e04a0a90 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Thu, 29 Jun 2023 13:32:59 -0600 Subject: [PATCH 3/3] prepare for release --- CHANGELOG.md | 2 +- blueprints.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ad848e..a360aac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,5 @@ # v3.7.6 -## mm/dd/2023 +## 06/29/2023 1. [](#bugfix) * Don't save an empty user file on password reset of non-existing user diff --git a/blueprints.yaml b/blueprints.yaml index bd7b61b..ce93d34 100644 --- a/blueprints.yaml +++ b/blueprints.yaml @@ -1,7 +1,7 @@ name: Login slug: login type: plugin -version: 3.7.5 +version: 3.7.6 testing: false description: Enables user authentication and login screen. icon: sign-in