diff --git a/application/config/config-defaults.php b/application/config/config-defaults.php index 0aa62dbb3d2..d77057c7ea7 100644 --- a/application/config/config-defaults.php +++ b/application/config/config-defaults.php @@ -315,6 +315,13 @@ */ $config['showrelevance'] = false; +/** +* To prevent brute force against forgotten password functionality, there is a random delay +* that prevent attacker from knowing whether username and email address are valid or not. +*/ +$config['minforgottenpasswordemaildelay'] = 500000; +$config['maxforgottenpasswordemaildelay'] = 1500000; + /** * PDF Export Settings * This feature configures PDF export for Export Answers diff --git a/application/controllers/admin/authentication.php b/application/controllers/admin/authentication.php index 3d3103bef3b..fd6bd9eb9c2 100644 --- a/application/controllers/admin/authentication.php +++ b/application/controllers/admin/authentication.php @@ -145,18 +145,19 @@ public function forgotpassword() $aFields = User::model()->findAllByAttributes(array('users_name' => $sUserName, 'email' => $sEmailAddr)); + // Preventing attacker from easily knowing whether the user and email address are valid or not (and slowing down brute force attacks) + usleep(rand(Yii::app()->getConfig("minforgottenpasswordemaildelay"),Yii::app()->getConfig("maxforgottenpasswordemaildelay"))); + if (count($aFields) < 1) { // wrong or unknown username and/or email - $aData['errormsg'] = $this->getController()->lang->gT('User name and/or email not found!'); - $aData['maxattempts'] = ''; - $this->_renderWrappedTemplate('authentication', 'error', $aData); + $aData['message'] = '
'.gT('If username and email that you specified are valid, a new password has been sent to you').'
'; } else { - $aData['message'] = $this->_sendPasswordEmail($sEmailAddr, $aFields); - $this->_renderWrappedTemplate('authentication', 'message', $aData); + $aData['message'] = '
'.$this->_sendPasswordEmail($sEmailAddr, $aFields).'
'; } + $this->_renderWrappedTemplate('authentication', 'message', $aData); } } @@ -189,12 +190,11 @@ private function _sendPasswordEmail($sEmailAddr, $aFields) if (SendEmailMessage($body, $sSubject, $sTo, $sFrom, $sSiteName, false, $sSiteAdminBounce)) { User::model()->updatePassword($aFields[0]['uid'], $sNewPass); - $sMessage = $username . '
' . $email . '

' . $clang->gT('An email with your login data was sent to you.'); + $sMessage = gT('If username and email that you specified are valid, a new password has been sent to you'); } else { - $sTmp = str_replace("{NAME}", '' . $aFields[0]['users_name'] . '', $clang->gT("Email to {NAME} ({EMAIL}) failed.")); - $sMessage = str_replace("{EMAIL}", $sEmailAddr, $sTmp) . '
'; + $sMessage = gT("Email failed."); } return $sMessage;