CVE-2019-18986 (published 2019-11-15T05:15Z)

Pimcore before 6.2.2 allow attackers to brute-force (guess) valid usernames by using the 'forgot password' functionality as it returns distinct messages for invalid password and non-existing users.

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

Weakness information:
cwe_id: CWE-307
cwe_name: Improper Restriction of Excessive Authentication Attempts
description: The product does not implement sufficient measures to prevent multiple failed authentication attempts within a short time frame, making it more susceptible to brute force attacks.
extended_description: 
            
            
            
         
         

Fix information:
repo_url: https://github.com/pimcore/pimcore
commit_details: repo_url: https://github.com/pimcore/pimcore
author: Bernhard Rusch
author_date: 2019-10-21 16:47:15+02:00
msg: Lost password service: do not expose info whether a user exists or not (avoid brute-force attacks)
repository: repo_url: https://github.com/pimcore/pimcore
repo_name: pimcore/pimcore
description: Core Framework for the Open Source Data & Experience Management Platform (PIM, MDM, CDP, DAM, DXP/CMS & Digital Commerce)
repo_language: PHP
owner: pimcore
file_changes: filename: LoginController.php
change_type: ModificationType.MODIFY
diff: @@ -22,6 +22,7 @@ use Pimcore\Controller\Configuration\TemplatePhp;
 use Pimcore\Controller\EventedControllerInterface;
 use Pimcore\Event\Admin\Login\LostPasswordEvent;
 use Pimcore\Event\AdminEvents;
+use Pimcore\Logger;
 use Pimcore\Model\User;
 use Pimcore\Templating\Model\ViewModel;
 use Pimcore\Tool;
@@ -116,29 +117,28 @@ class LoginController extends AdminController implements BruteforceProtectedCont
     public function lostpasswordAction(Request $request, BruteforceProtectionHandler $bruteforceProtectionHandler)
     {
         $view = $this->buildLoginPageViewModel();
-        $view->success = false;
+        $error = null;
 
-        // TODO is the error on the view used somewhere?
         if ($request->getMethod() === 'POST' && $username = $request->get('username')) {
             $user = User::getByName($username);
 
             if ($user instanceof User) {
                 if (!$user->isActive()) {
-                    $view->error = 'user inactive';
+                    $error = 'user inactive';
                 }
 
                 if (!$user->getEmail()) {
-                    $view->error = 'user has no email address';
+                    $error = 'user has no email address';
                 }
 
                 if (!$user->getPassword()) {
-                    $view->error = 'user has no password';
+                    $error = 'user has no password';
                 }
             } else {
-                $view->error = 'user unknown';
+                $error = 'user unknown';
             }
 
-            if (!$view->error) {
+            if (!$error) {
                 $token = Authentication::generateToken($username, $user->getPassword());
 
                 $loginUrl = $this->generateUrl('pimcore_admin_login_check', [
@@ -163,14 +163,13 @@ class LoginController extends AdminController implements BruteforceProtectedCont
                     if ($event->hasResponse()) {
                         return $event->getResponse();
                     }
-
-                    $view->success = true;
                 } catch (\Exception $e) {
-                    $view->error = 'could not send email';
+                    $error = 'could not send email';
                 }
             }
 
-            if ($view->error) {
+            if ($error) {
+                Logger::error('Lost password service: ' . $error);
                 $bruteforceProtectionHandler->addEntry($request->get('username'), $request);
             }
         }

programming_language: PHP
filename: lostpassword.html.php
change_type: ModificationType.MODIFY
diff: @@ -8,23 +8,16 @@ $this->get("translate")->setDomain("admin");
 
 
 
-<?php if ($this->success) { ?>
-    <div class="text info">
+<?php if ($this->getRequest()->getMethod() === 'POST') { ?>
+    <div class="text error">
         <?= $this->translate("A temporary login link has been sent to your email address."); ?>
         <br/>
         <?= $this->translate("Please check your mailbox."); ?>
     </div>
 <?php } else { ?>
-    <?php if ($this->error) { ?>
-        <div class="text error">
-            <?= $this->translate('lostpassword_reset_error'); ?>
-        </div>
-    <?php } else { ?>
-        <div class="text info">
-            <?= $this->translate("Enter your username and pimcore will send a login link to your email address"); ?>
-        </div>
-    <?php } ?>
-
+    <div class="text info">
+        <?= $this->translate("Enter your username and pimcore will send a login link to your email address"); ?>
+    </div>
 
     <form method="post" action="<?= $view->router()->path('pimcore_admin_login_lostpassword') ?>">
         <input type="text" name="username" placeholder="<?= $this->translate("Username"); ?>" required autofocus>

programming_language: PHP
filename: en.json
change_type: ModificationType.MODIFY
diff: @@ -147,7 +147,6 @@
   "send": "Send",
   "Password": "Password",
   "Forgot your password": "Forgot your password",
-  "lostpassword_reset_error": "There was an error while sending the lost password info. Please try again or contact your administrator.",
   "Back to Login": "Back to Login",
   "Enter your username and pimcore will send a login link to your email address": "Enter your username and Pimcore will send a login link to your email address",
   "Please check your mailbox.": "Please check your mailbox.",

programming_language: Python