VYPR
Unrated severityNVD Advisory· Published Jul 2, 2020· Updated Aug 4, 2024

Improper Authentication

CVE-2020-4074

Description

In PrestaShop from version 1.5.0.0 and before version 1.7.6.6, the authentication system is malformed and an attacker is able to forge requests and execute admin commands. The problem is fixed in 1.7.6.6.

Affected products

1

Patches

2
b2956eec991d

// Changelog 1.7.6.6

1 file changed · +38 4
  • docs/CHANGELOG.txt+38 4 modified
    @@ -1,11 +1,11 @@
    -2007-2019 PrestaShop and Contributors
    +2007-2020 PrestaShop 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:
    -http://opensource.org/licenses/osl-3.0.php
    +https://opensource.org/licenses/osl-3.0.php
     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.
    @@ -17,13 +17,47 @@ versions in the future. If you wish to customize PrestaShop for your
     needs please refer to http://www.prestashop.com for more information.
     
     @author    PrestaShop SA <contact@prestashop.com>
    -@copyright 2007-2019 PrestaShop SA and Contributors
    -@license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
    +@copyright 2007-2020 PrestaShop SA and Contributors
    +@license   https://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
     International Registered Trademark & Property of PrestaShop SA
     
     Release Notes for PrestaShop 1.7
     --------------------------------
     
    +####################################
    +#   v1.7.6.6 - (2020-07-01)
    +####################################
    +- Back Office:
    +  - Bug fix:
    +    - #19814: Change buttons in modal bulk of module page to avoid black color (by @NeOMakinG)
    +    - #18975: BO - Customer View page - Added Green alert when editing a voucher (by @Progi1984)
    +    - #19942: Cast changelogs to array for twig - Backport of #19778 (by @atomiix)
    +    - #19718: Remove i18n access restrictions (by @PierreRambaud)
    +    - #19990: Fix BO page Module permission checks (by @jolelievre)
    +- Front Office:
    +  - Improvement:
    +    - #19800: Add a new selector in order to select the product page more precisely (by @NeOMakinG)
    +- Core:
    +  - Improvement:
    +    - #19943: Update Composer dependencies and prestashop module versions (by @PierreRambaud)
    +    - #19980: Update version number to 1.7.6.6 (by @matks)
    +    - #19979: Update outdated assets in 176x (by @matks)
    +    - #19984: Update license headers for PS 1.7.6.6 (by @matks)
    +  - Bug fix:
    +    - #19010: Added missing required_once for Datas class (by @atomiix)
    +    - #19986: Fix php7-only code into 1766 (by @matks)
    +    - #20018: Remove COLLATION placeholder from 1.7.6.6.sql (by @matks)
    +    - #GHSA-mc98-xjm3-c4fm - External control of configuration setting in the dashboard (by @PierreRambaud)
    +    - #GHSA-997j-f42g-x57c - Information exposure in upload directory (by @PierreRambaud)
    +    - #GHSA-492w-2pp5-xhvg - Information disclosure in release archive (by @PierreRambaud)
    +    - #GHSA-ccvh-jh5x-mpg4 - Improper authentication (by @PierreRambaud)
    +    - #GHSA-xp3x-3h8q-c386 - Improper access controls in Carrier page, Module Manager and Module Positions (by @PierreRambaud)
    +    - #GHSA-qgh4-95j7-p3vj - Reflected XSS in product page (by @PierreRambaud)
    +    - #GHSA-v4pg-q2cv-f7x4 - Stored XSS in AdminQuickAccesses (by @PierreRambaud)
    +- Web Services:
    +  - Bug fix:
    +    - #18969: Make api backward compatible for Currencies (by @atomiix)
    +
     ####################################
     #   v1.7.6.5 - (2020-04-17)
     ####################################
    
30b6a7bdaca9

Merge pull request from GHSA-ccvh-jh5x-mpg4

https://github.com/prestashop/prestashopMathieu FermentJun 29, 2020via osv
11 files changed · +404 6
  • classes/Context.php+2 0 modified
    @@ -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());
         }
     
         /**
    
  • classes/Cookie.php+91 1 modified
    @@ -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
     {
    @@ -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;
    @@ -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;
    +    }
     }
    
  • classes/Customer.php+7 1 modified
    @@ -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()
    +        ;
         }
     
         /**
    
  • classes/CustomerSession.php+89 0 added
    @@ -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;
    +    }
    +}
    
  • classes/Employee.php+11 2 modified
    @@ -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);
     
    @@ -500,6 +508,7 @@ public function logout()
                 Context::getContext()->cookie->logout();
                 Context::getContext()->cookie->write();
             }
    +
             $this->id = null;
         }
     
    
  • classes/EmployeeSession.php+89 0 added
    @@ -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;
    +    }
    +}
    
  • classes/form/CustomerPersister.php+2 2 modified
    @@ -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)
    
  • controllers/admin/AdminLoginController.php+1 0 modified
    @@ -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();
    
  • install-dev/data/db_structure.sql+14 0 modified
    @@ -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;
    
  • install-dev/upgrade/sql/1.7.6.6.sql+16 0 added
    @@ -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;
    
  • src/Core/Session/SessionInterface.php+82 0 added
    @@ -0,0 +1,82 @@
    +<?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
    + */
    +
    +namespace PrestaShop\PrestaShop\Core\Session;
    +
    +/**
    + * SessionInterface is used to store/access to the session token used by customers and employees
    + */
    +interface SessionInterface
    +{
    +    /**
    +     * Returns session id
    +     *
    +     * @return int
    +     */
    +    public function getId();
    +
    +    /**
    +     * Set session user id
    +     *
    +     * @param int $id
    +
    +     * @return void
    +     */
    +    public function setUserId($id);
    +
    +    /**
    +     * Returns session user id
    +     *
    +     * @return int
    +     */
    +    public function getUserId();
    +
    +    /**
    +     * Set session token
    +     *
    +     * @param string $string
    +     *
    +     * @return void
    +     */
    +    public function setToken($string);
    +
    +    /**
    +     * Returns session token
    +     *
    +     * @return string
    +     */
    +    public function getToken();
    +
    +    /**
    +     * Adds current object to the database.
    +     */
    +    public function add();
    +
    +    /**
    +     * Deletes current object from database.
    +     */
    +    public function delete();
    +}
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

2

News mentions

0

No linked articles in our index yet.