Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Weak token implementation #12017

Merged
merged 1 commit into from Jan 22, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
89 changes: 47 additions & 42 deletions controllers/front/PasswordController.php
Expand Up @@ -109,14 +109,24 @@ protected function changePassword()
{
$token = Tools::getValue('token');
$id_customer = (int) Tools::getValue('id_customer');
if ($email = Db::getInstance()->getValue('SELECT `email` FROM ' . _DB_PREFIX_ . 'customer c WHERE c.`secure_key` = \'' . pSQL($token) . '\' AND c.id_customer = ' . $id_customer)) {
$reset_token = Tools::getValue('reset_token');
$email = Db::getInstance()->getValue(
'SELECT `email` FROM ' . _DB_PREFIX_ . 'customer c WHERE c.`secure_key` = \'' . pSQL($token) . '\' AND c.id_customer = ' . $id_customer
);
if ($email) {
$customer = new Customer();
$customer->getByEmail($email);

if (!Validate::isLoadedObject($customer)) {
$this->errors[] = $this->trans('Customer account not found', array(), 'Shop.Notifications.Error');
} elseif (!$customer->active) {
$this->errors[] = $this->trans('You cannot regenerate the password for this account.', array(), 'Shop.Notifications.Error');
} elseif ($customer->getValidResetPasswordToken() !== $reset_token) {
$this->errors[] = $this->trans('The password change request expired. You should ask for a new one.', array(), 'Shop.Notifications.Error');
}

if ($this->errors) {
return;
}

if ($isSubmit = Tools::isSubmit('passwd')) {
Expand Down Expand Up @@ -146,59 +156,54 @@ protected function changePassword()
'customer_email' => $customer->email,
'customer_token' => $token,
'id_customer' => $id_customer,
'reset_token' => Tools::getValue('reset_token'),
'reset_token' => $reset_token,
]);

$this->setTemplate('customer/password-new');
} else {
// Both password fields posted. Check if all is right and store new password properly.
if (!Tools::getValue('reset_token') || (strtotime($customer->last_passwd_gen . '+' . (int) Configuration::get('PS_PASSWD_TIME_FRONT') . ' minutes') - time()) > 0) {
if (!$reset_token || (strtotime($customer->last_passwd_gen . '+' . (int) Configuration::get('PS_PASSWD_TIME_FRONT') . ' minutes') - time()) > 0) {
Tools::redirect('index.php?controller=authentication&error_regen_pwd');
} else {
// To update password, we must have the temporary reset token that matches.
if ($customer->getValidResetPasswordToken() !== Tools::getValue('reset_token')) {
$this->errors[] = $this->trans('The password change request expired. You should ask for a new one.', array(), 'Shop.Notifications.Error');
} else {
$customer->passwd = $this->get('hashing')->hash($password = Tools::getValue('passwd'), _COOKIE_KEY_);
$customer->last_passwd_gen = date('Y-m-d H:i:s', time());
$customer->passwd = $this->get('hashing')->hash($password = Tools::getValue('passwd'), _COOKIE_KEY_);
$customer->last_passwd_gen = date('Y-m-d H:i:s', time());

if ($customer->update()) {
Hook::exec('actionPasswordRenew', array('customer' => $customer, 'password' => $password));
$customer->removeResetPasswordToken();
$customer->update();
if ($customer->update()) {
Hook::exec('actionPasswordRenew', array('customer' => $customer, 'password' => $password));
$customer->removeResetPasswordToken();
$customer->update();

$mail_params = [
'{email}' => $customer->email,
'{lastname}' => $customer->lastname,
'{firstname}' => $customer->firstname,
];
$mail_params = [
'{email}' => $customer->email,
'{lastname}' => $customer->lastname,
'{firstname}' => $customer->firstname,
];

if (
Mail::Send(
$this->context->language->id,
'password',
$this->trans(
'Your new password',
array(),
'Emails.Subject'
),
$mail_params,
$customer->email,
$customer->firstname . ' ' . $customer->lastname
)
) {
$this->context->smarty->assign([
'customer_email' => $customer->email,
]);
$this->success[] = $this->trans('Your password has been successfully reset and a confirmation has been sent to your email address: %s', array($customer->email), 'Shop.Notifications.Success');
$this->context->updateCustomer($customer);
$this->redirectWithNotifications('index.php?controller=my-account');
} else {
$this->errors[] = $this->trans('An error occurred while sending the email.', array(), 'Shop.Notifications.Error');
}
if (
Mail::Send(
$this->context->language->id,
'password',
$this->trans(
'Your new password',
array(),
'Emails.Subject'
),
$mail_params,
$customer->email,
$customer->firstname . ' ' . $customer->lastname
)
) {
$this->context->smarty->assign([
'customer_email' => $customer->email,
]);
$this->success[] = $this->trans('Your password has been successfully reset and a confirmation has been sent to your email address: %s', array($customer->email), 'Shop.Notifications.Success');
$this->context->updateCustomer($customer);
$this->redirectWithNotifications('index.php?controller=my-account');
} else {
$this->errors[] = $this->trans('An error occurred with your account, which prevents us from updating the new password. Please report this issue using the contact form.', array(), 'Shop.Notifications.Error');
$this->errors[] = $this->trans('An error occurred while sending the email.', array(), 'Shop.Notifications.Error');
}
} else {
$this->errors[] = $this->trans('An error occurred with your account, which prevents us from updating the new password. Please report this issue using the contact form.', array(), 'Shop.Notifications.Error');
}
}
}
Expand Down