Skip to content
Permalink
Browse files Browse the repository at this point in the history
Merge pull request from GHSA-ccvh-jh5x-mpg4
Improper authentication
  • Loading branch information
matks committed Jun 29, 2020
2 parents 35ef7e9 + 31b896d commit 30b6a7b
Show file tree
Hide file tree
Showing 11 changed files with 404 additions and 6 deletions.
2 changes: 2 additions & 0 deletions classes/Context.php
Expand Up @@ -359,6 +359,8 @@ public function updateCustomer(Customer $customer)
$this->cookie->id_cart = (int) $this->cart->id;
$this->cookie->write();
$this->cart->autosetProductAddress();

$this->cookie->registerSession(new CustomerSession());
}

/**
Expand Down
92 changes: 91 additions & 1 deletion classes/Cookie.php
Expand Up @@ -24,6 +24,8 @@
* International Registered Trademark & Property of PrestaShop SA
*/
use Defuse\Crypto\Key;
use PrestaShop\PrestaShop\Core\Exception\CoreException;
use PrestaShop\PrestaShop\Core\Session\SessionInterface;

class CookieCore
{
Expand Down Expand Up @@ -246,7 +248,8 @@ public function isLoggedBack()
*/
public function logout()
{
$this->_content = array();
$this->deleteSession();
$this->_content = [];
$this->encryptAndSetCookie();
unset($_COOKIE[$this->_name]);
$this->_modified = true;
Expand Down Expand Up @@ -453,4 +456,91 @@ public function exists()
{
return isset($_COOKIE[$this->_name]);
}

/**
* Register a new session
*
* @param SessionInterface $session
*/
public function registerSession(SessionInterface $session)
{
if (isset($this->id_employee)) {
$session->setUserId((int) $this->id_employee);
} elseif (isset($this->id_customer)) {
$session->setUserId((int) $this->id_customer);
} else {
throw new CoreException('Invalid user id');
}

$session->setToken(sha1(time() . uniqid()));
$session->add();

$this->session_id = $session->getId();
$this->session_token = $session->getToken();
}

/**
* Delete session
*
* @return bool
*/
public function deleteSession()
{
if (!isset($this->session_id)) {
return false;
}

$session = $this->getSession($this->session_id);
if ($session !== null) {
$session->delete();

return true;
}

return false;
}

/**
* Check if this session is still alive
*
* @return bool
*/
public function isSessionAlive()
{
if (!isset($this->session_id, $this->session_token)) {
return false;
}

$session = $this->getSession($this->session_id);

return
$session !== null
&& $session->getToken() === $this->session_token
&& (
(int) $this->id_employee === $session->getUserId()
|| (int) $this->id_customer === $session->getUserId()
)
;
}

/**
* Retrieve session based on a session id and the employee or
* customer id
*
* @return SessionInterface|null
*/
public function getSession($sessionId)
{
if (isset($this->id_employee)) {
$session = new EmployeeSession($sessionId);
} elseif (isset($this->id_customer)) {
$session = new CustomerSession($sessionId);
}

if (!empty($session->getId())) {
return $session;
}

return null;
}
}
8 changes: 7 additions & 1 deletion classes/Customer.php
Expand Up @@ -1187,7 +1187,13 @@ public function isLogged($withGuest = false)
}

/* Customer is valid only if it can be load and if object password is the same as database one */
return $this->logged == 1 && $this->id && Validate::isUnsignedId($this->id) && Customer::checkPassword($this->id, $this->passwd);
return
$this->logged == 1
&& $this->id
&& Validate::isUnsignedId($this->id)
&& Customer::checkPassword($this->id, $this->passwd)
&& Context::getContext()->cookie->isSessionAlive()
;
}

/**
Expand Down
89 changes: 89 additions & 0 deletions classes/CustomerSession.php
@@ -0,0 +1,89 @@
<?php
/**
* 2007-2020 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
use PrestaShop\PrestaShop\Core\Session\SessionInterface;

class CustomerSessionCore extends ObjectModel implements SessionInterface
{
public $id;

/** @var Id Customer */
public $id_customer;

/** @var string Token */
public $token;

/**
* @see ObjectModel::$definition
*/
public static $definition = [
'table' => 'customer_session',
'primary' => 'id_customer_session',
'fields' => [
'id_customer' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true],
'token' => ['type' => self::TYPE_STRING, 'validate' => 'isSha1', 'size' => 40, 'copy_post' => false],
],
];

/**
* {@inheritdoc}
*/
public function getId()
{
return $this->id;
}

/**
* {@inheritdoc}
*/
public function setUserId($idCustomer)
{
$this->id_customer = (int) $idCustomer;
}

/**
* {@inheritdoc}
*/
public function getUserId()
{
return (int) $this->id_customer;
}

/**
* {@inheritdoc}
*/
public function setToken($token)
{
$this->token = (string) $token;
}

/**
* {@inheritdoc}
*/
public function getToken()
{
return $this->token;
}
}
13 changes: 11 additions & 2 deletions classes/Employee.php
Expand Up @@ -480,8 +480,16 @@ public function isLoggedBack()
if (!Cache::isStored('isLoggedBack' . $this->id)) {
/* Employee is valid only if it can be load and if cookie password is the same as database one */
$result = (
$this->id && Validate::isUnsignedId($this->id) && Context::getContext()->cookie && Employee::checkPassword($this->id, Context::getContext()->cookie->passwd)
&& (!isset(Context::getContext()->cookie->remote_addr) || Context::getContext()->cookie->remote_addr == ip2long(Tools::getRemoteAddr()) || !Configuration::get('PS_COOKIE_CHECKIP'))
$this->id
&& Validate::isUnsignedId($this->id)
&& Context::getContext()->cookie
&& Context::getContext()->cookie->isSessionAlive()
&& Employee::checkPassword($this->id, Context::getContext()->cookie->passwd)
&& (
!isset(Context::getContext()->cookie->remote_addr)
|| Context::getContext()->cookie->remote_addr == ip2long(Tools::getRemoteAddr())
|| !Configuration::get('PS_COOKIE_CHECKIP')
)
);
Cache::store('isLoggedBack' . $this->id, $result);

Expand All @@ -500,6 +508,7 @@ public function logout()
Context::getContext()->cookie->logout();
Context::getContext()->cookie->write();
}

$this->id = null;
}

Expand Down
89 changes: 89 additions & 0 deletions classes/EmployeeSession.php
@@ -0,0 +1,89 @@
<?php
/**
* 2007-2020 PrestaShop SA and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
use PrestaShop\PrestaShop\Core\Session\SessionInterface;

class EmployeeSessionCore extends ObjectModel implements SessionInterface
{
public $id;

/** @var int Id Employee */
public $id_employee;

/** @var string Token */
public $token;

/**
* @see ObjectModel::$definition
*/
public static $definition = [
'table' => 'employee_session',
'primary' => 'id_employee_session',
'fields' => [
'id_employee' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true],
'token' => ['type' => self::TYPE_STRING, 'validate' => 'isSha1', 'size' => 40, 'copy_post' => false],
],
];

/**
* {@inheritdoc}
*/
public function getId()
{
return $this->id;
}

/**
* {@inheritdoc}
*/
public function setUserId($idEmployee)
{
$this->id_employee = (int) $idEmployee;
}

/**
* {@inheritdoc}
*/
public function getUserId()
{
return (int) $this->id_employee;
}

/**
* {@inheritdoc}
*/
public function setToken($token)
{
$this->token = (string) $token;
}

/**
* {@inheritdoc}
*/
public function getToken()
{
return $this->token;
}
}
4 changes: 2 additions & 2 deletions classes/form/CustomerPersister.php
Expand Up @@ -55,9 +55,9 @@ public function save(Customer $customer, $clearTextPassword, $newPassword = '',
{
if ($customer->id) {
return $this->update($customer, $clearTextPassword, $newPassword, $passwordRequired);
} else {
return $this->create($customer, $clearTextPassword);
}

return $this->create($customer, $clearTextPassword);
}

private function update(Customer $customer, $clearTextPassword, $newPassword, $passwordRequired = true)
Expand Down
1 change: 1 addition & 0 deletions controllers/admin/AdminLoginController.php
Expand Up @@ -213,6 +213,7 @@ public function processLogin()
$cookie->profile = $this->context->employee->id_profile;
$cookie->passwd = $this->context->employee->passwd;
$cookie->remote_addr = $this->context->employee->remote_addr;
$cookie->registerSession(new EmployeeSession());

if (!Tools::getValue('stay_logged_in')) {
$cookie->last_activity = time();
Expand Down
14 changes: 14 additions & 0 deletions install-dev/data/db_structure.sql
Expand Up @@ -2829,3 +2829,17 @@ CREATE TABLE IF NOT EXISTS `PREFIX_cms_role_lang` (
`id_cms_role`, `id_lang`, id_shop
)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8;

CREATE TABLE `PREFIX_employee_session` (
`id_employee_session` int(11) unsigned NOT NULL auto_increment,
`id_employee` int(10) unsigned DEFAULT NULL,
`token` varchar(40) DEFAULT NULL,
PRIMARY KEY `id_employee_session` (`id_employee_session`)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8 COLLATION;

CREATE TABLE `PREFIX_customer_session` (
`id_customer_session` int(11) unsigned NOT NULL auto_increment,
`id_customer` int(10) unsigned DEFAULT NULL,
`token` varchar(40) DEFAULT NULL,
PRIMARY KEY `id_customer_session` (`id_customer_session`)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8 COLLATION;
16 changes: 16 additions & 0 deletions install-dev/upgrade/sql/1.7.6.6.sql
@@ -0,0 +1,16 @@
SET SESSION sql_mode='';
SET NAMES 'utf8';

CREATE TABLE `PREFIX_employee_session` (
`id_employee_session` int(11) unsigned NOT NULL auto_increment,
`id_employee` int(10) unsigned DEFAULT NULL,
`token` varchar(40) DEFAULT NULL,
PRIMARY KEY `id_employee_session` (`id_employee_session`)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8 COLLATION;

CREATE TABLE `PREFIX_customer_session` (
`id_customer_session` int(11) unsigned NOT NULL auto_increment,
`id_customer` int(10) unsigned DEFAULT NULL,
`token` varchar(40) DEFAULT NULL,
PRIMARY KEY `id_customer_session` (`id_customer_session`)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8 COLLATION;

0 comments on commit 30b6a7b

Please sign in to comment.