summaryrefslogtreecommitdiffstats
path: root/glpi-security2.patch
diff options
context:
space:
mode:
authorRemi Collet <remi@remirepo.net>2019-03-27 16:06:47 +0100
committerRemi Collet <remi@remirepo.net>2019-03-27 16:06:47 +0100
commit6c1dfcb9214ecbf010719a846c8b3b8ea38f2653 (patch)
treeb5ac692ee2b863e32edc58a95f182e78f1114bd7 /glpi-security2.patch
parent87c0348084cb603dd1e03474502c3ab6366e273f (diff)
add security fix backported from 9.4.1:
[security] Bad chevrons rendering on dropdowns [security] Iframe and forms are rendered in rich text contents [security] Type juggling authentication bypass [security] Malicious images upload [security] Password token date was not reset [security] Prevent timed attack and enforce cookie security
Diffstat (limited to 'glpi-security2.patch')
-rw-r--r--glpi-security2.patch292
1 files changed, 292 insertions, 0 deletions
diff --git a/glpi-security2.patch b/glpi-security2.patch
new file mode 100644
index 0000000..254c47a
--- /dev/null
+++ b/glpi-security2.patch
@@ -0,0 +1,292 @@
+From 9cd45a1ec1932189fc5295e0f9978b36ab5eecaa Mon Sep 17 00:00:00 2001
+From: Remi Collet <remi@remirepo.net>
+Date: Wed, 27 Mar 2019 14:55:25 +0100
+Subject: [PATCH] Fix/cookie auth (#5562) * prevent timed attack * add new
+ field for storing cookie token and reverse the verification (we store the
+ hash on our side and not client side)
+
+Backported from 9.4 26900a5e53a5ad347d20a947eb5f7e2b447fef9f
+
+Check cookie validity on glpi side
+
+Backported from 9.4 a3ab29c77c6fc7a45a7b0ef71c4442aee62acda6
+
+Hack for DB Schema
+
+As 9.3.3 use dbschema 9.3.2, we can switch to 9.3.3
+Migration detection use dbversion, so will be raised
+Script execution use version, which allow to keep it unchanged
+More 9.4 is aware of 9.3.3 (not of 9.4)
+---
+ inc/auth.class.php | 19 ++++-------
+ inc/define.php | 2 +-
+ inc/update.class.php | 7 +++-
+ inc/user.class.php | 64 ++++++++++++++++++++++++++++++------
+ install/mysql/glpi-empty.sql | 10 +++---
+ install/update_932_933.php | 63 +++++++++++++++++++++++++++++++++++
+ 6 files changed, 136 insertions(+), 29 deletions(-)
+ create mode 100644 install/update_932_933.php
+
+diff --git a/inc/auth.class.php b/inc/auth.class.php
+index 707d7ab31..67d361653 100644
+--- a/inc/auth.class.php
++++ b/inc/auth.class.php
+@@ -500,11 +500,11 @@ class Auth extends CommonGLPI {
+ if (count($data) === 2) {
+ list ($cookie_id, $cookie_token) = $data;
+
+- $token = User::getToken($cookie_id, 'personal_token');
++ $user = new User();
++ $user->getFromDB($cookie_id);
++ $hash = $user->getAuthToken('cookie_token');
+
+- if ($token !== false && Auth::checkPassword($token, $cookie_token)) {
+- $user = new User();
+- $user->getFromDB($cookie_id); //true if $token is not false
++ if (Auth::checkPassword($cookie_token, $hash)) {
+ $this->user->fields['name'] = $user->fields['name'];
+ return true;
+ } else {
+@@ -848,12 +848,7 @@ class Auth extends CommonGLPI {
+ }
+
+ if ($this->auth_succeded && $CFG_GLPI['login_remember_time'] > 0 && $remember_me) {
+- $token = false;
+- if (!empty($this->user->fields['personal_token'])) {
+- $token = $this->user->fields['personal_token'];
+- } else {
+- $token = User::getToken($this->user->fields['id'], 'personal_token');
+- }
++ $token = $this->user->getAuthToken('cookie_token', true);
+
+ if ($token) {
+ //Cookie name (Allow multiple GLPI)
+@@ -861,11 +856,9 @@ class Auth extends CommonGLPI {
+ //Cookie session path
+ $cookie_path = ini_get('session.cookie_path');
+
+- $hash = Auth::getPasswordHash($token);
+-
+ $data = json_encode([
+ $this->user->fields['id'],
+- $hash,
++ $token,
+ ]);
+
+ //Send cookie to browser
+diff --git a/inc/define.php b/inc/define.php
+index 78125529e..22830bc05 100644
+--- a/inc/define.php
++++ b/inc/define.php
+@@ -41,7 +41,7 @@ if (substr(GLPI_VERSION, -4) === '-dev') {
+ );
+ } else {
+ //for stable version
+- define("GLPI_SCHEMA_VERSION", '9.3.2');
++ define("GLPI_SCHEMA_VERSION", '9.3.3');
+ }
+ define('GLPI_MIN_PHP', '5.6.0'); // Must also be changed in top of index.php
+ define('GLPI_YEAR', '2018');
+diff --git a/inc/update.class.php b/inc/update.class.php
+index fec2271c0..e3da3c9f0 100644
+--- a/inc/update.class.php
++++ b/inc/update.class.php
+@@ -431,7 +431,12 @@ class Update extends CommonGLPI {
+ case "9.3.1":
+ include_once "{$updir}update_931_932.php";
+ update931to932();
+- break;
++
++ case "9.3.2":
++ case "9.3.3":
++ // post 9.3.3
++ include_once "{$updir}update_932_933.php";
++ update932to933();
+
+ case GLPI_VERSION:
+ case GLPI_SCHEMA_VERSION:
+diff --git a/inc/user.class.php b/inc/user.class.php
+index 67bfc7149..d4139edfa 100644
+--- a/inc/user.class.php
++++ b/inc/user.class.php
+@@ -4595,26 +4595,70 @@ class User extends CommonDBTM {
+ }
+
+
+- /**
++ /**
++ * Get token of a user. If it does not exists then generate it.
++ *
++ * @since 9.4
++ *
++ * @param string $field the field storing the token
++ * @param boolean $force_new force generation of a new token
++ *
++ * @return string|false token or false in case of error
++ */
++ public function getAuthToken($field = 'personal_token', $force_new = false) {
++ global $CFG_GLPI;
++
++ if ($this->isNewItem()) {
++ return false;
++ }
++
++ // check date validity for cookie token
++ $outdated = false;
++ if ($field === 'cookie_token') {
++ $date_create = new DateTime($this->fields[$field."_date"]);
++ $date_expir = $date_create->add(new DateInterval('PT'.$CFG_GLPI["login_remember_time"].'S'));
++
++ if ($date_expir < new DateTime()) {
++ $outdated = true;
++ }
++ }
++
++ // token exists, is not oudated, and we may use it
++ if (!empty($this->fields[$field]) && !$force_new && !$outdated) {
++ return $this->fields[$field];
++ }
++
++ // else get a new token
++ $token = self::getUniqueToken($field);
++
++ // for cookie token, we need to store it hashed
++ $hash = $token;
++ if ($field === 'cookie_token') {
++ $hash = Auth::getPasswordHash($token);
++ }
++
++ // save this token in db
++ $this->update(['id' => $this->getID(),
++ $field => $hash,
++ $field . "_date" => $_SESSION['glpi_currenttime']]);
++
++ return $token;
++ }
++
++/**
+ * Get token of a user. If not exists generate it.
+ *
+ * @param integer $ID User ID
+ * @param string $field Field storing the token
++ * @param boolean $force_new force generation of a new token
+ *
+ * @return string|boolean User token, false if user does not exist
+ */
+- static function getToken($ID, $field = 'personal_token') {
++ static function getToken($ID, $field = 'personal_token', $force_new = false) {
+
+ $user = new self();
+ if ($user->getFromDB($ID)) {
+- if (!empty($user->fields[$field])) {
+- return $user->fields[$field];
+- }
+- $token = self::getUniqueToken($field);
+- $user->update(['id' => $user->getID(),
+- $field => $token,
+- $field . "_date" => $_SESSION['glpi_currenttime']]);
+- return $user->fields[$field];
++ return $user->getAuthToken($field, $force_new);
+ }
+
+ return false;
+diff --git a/install/mysql/glpi-empty.sql b/install/mysql/glpi-empty.sql
+index abfe14600..14d6976c9 100644
+--- a/install/mysql/glpi-empty.sql
++++ b/install/mysql/glpi-empty.sql
+@@ -8850,6 +8850,8 @@ CREATE TABLE `glpi_users` (
+ `personal_token_date` datetime DEFAULT NULL,
+ `api_token` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
+ `api_token_date` datetime DEFAULT NULL,
++ `cookie_token` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
++ `cookie_token_date` datetime DEFAULT NULL,
+ `display_count_on_home` int(11) DEFAULT NULL,
+ `notification_to_myself` tinyint(1) DEFAULT NULL,
+ `duedateok_color` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
+@@ -8900,10 +8902,10 @@ CREATE TABLE `glpi_users` (
+ KEY `sync_field` (`sync_field`)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+
+-INSERT INTO `glpi_users` VALUES ('2','glpi','$2y$10$rXXzbc2ShaiCldwkw4AZL.n.9QSH7c0c9XJAyyjrbL9BwmWditAYm','','','','',NULL,'0',NULL,'0','20','1',NULL,'0','1','2014-06-18 08:02:24','2014-06-18 08:02:24',NULL,'0','0','0','0','0',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'0',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,'',NULL);
+-INSERT INTO `glpi_users` VALUES ('3','post-only','$2y$10$dTMar1F3ef5X/H1IjX9gYOjQWBR1K4bERGf4/oTPxFtJE/c3vXILm','','','','',NULL,'0','en_GB','0','20','1',NULL,'0','1',NULL,NULL,NULL,'0','0','0','0','0',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'0',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,'',NULL);
+-INSERT INTO `glpi_users` VALUES ('4','tech','$2y$10$.xEgErizkp6Az0z.DHyoeOoenuh0RcsX4JapBk2JMD6VI17KtB1lO','','','','',NULL,'0','en_GB','0','20','1',NULL,'0','1',NULL,NULL,NULL,'0','0','0','0','0',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'0',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,'',NULL);
+-INSERT INTO `glpi_users` VALUES ('5','normal','$2y$10$Z6doq4zVHkSPZFbPeXTCluN1Q/r0ryZ3ZsSJncJqkN3.8cRiN0NV.','','','','',NULL,'0','en_GB','0','20','1',NULL,'0','1',NULL,NULL,NULL,'0','0','0','0','0',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'0',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,'',NULL);
++INSERT INTO `glpi_users` VALUES ('2','glpi','$2y$10$rXXzbc2ShaiCldwkw4AZL.n.9QSH7c0c9XJAyyjrbL9BwmWditAYm','','','','',NULL,'0',NULL,'0','20','1',NULL,'0','1','2014-06-18 08:02:24','2014-06-18 08:02:24',NULL,'0','0','0','0','0',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'0',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,'',NULL);
++INSERT INTO `glpi_users` VALUES ('3','post-only','$2y$10$dTMar1F3ef5X/H1IjX9gYOjQWBR1K4bERGf4/oTPxFtJE/c3vXILm','','','','',NULL,'0','en_GB','0','20','1',NULL,'0','1',NULL,NULL,NULL,'0','0','0','0','0',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'0',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,'',NULL);
++INSERT INTO `glpi_users` VALUES ('4','tech','$2y$10$.xEgErizkp6Az0z.DHyoeOoenuh0RcsX4JapBk2JMD6VI17KtB1lO','','','','',NULL,'0','en_GB','0','20','1',NULL,'0','1',NULL,NULL,NULL,'0','0','0','0','0',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'0',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,'',NULL);
++INSERT INTO `glpi_users` VALUES ('5','normal','$2y$10$Z6doq4zVHkSPZFbPeXTCluN1Q/r0ryZ3ZsSJncJqkN3.8cRiN0NV.','','','','',NULL,'0','en_GB','0','20','1',NULL,'0','1',NULL,NULL,NULL,'0','0','0','0','0',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'0',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,'',NULL);
+
+ ### Dump table glpi_usertitles
+
+diff --git a/install/update_932_933.php b/install/update_932_933.php
+new file mode 100644
+index 000000000..240c5cb00
+--- /dev/null
++++ b/install/update_932_933.php
+@@ -0,0 +1,63 @@
++<?php
++/**
++ * ---------------------------------------------------------------------
++ * GLPI - Gestionnaire Libre de Parc Informatique
++ * Copyright (C) 2015-2017 Teclib' and contributors.
++ *
++ * http://glpi-project.org
++ *
++ * based on GLPI - Gestionnaire Libre de Parc Informatique
++ * Copyright (C) 2003-2014 by the INDEPNET Development Team.
++ *
++ * ---------------------------------------------------------------------
++ *
++ * LICENSE
++ *
++ * This file is part of GLPI.
++ *
++ * GLPI is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * GLPI is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with GLPI. If not, see <http://www.gnu.org/licenses/>.
++ * ---------------------------------------------------------------------
++ */
++
++/** @file
++* @brief
++*/
++
++/**
++ * Update from 9.3.2 to 9.3.3 (DB schema version, introduced post 9.3.3)
++ *
++ * @return bool for success (will die for most error)
++**/
++function update932to933() {
++ global $DB, $migration, $CFG_GLPI;
++
++ $current_config = Config::getConfigurationValues('core');
++ $updateresult = true;
++ $ADDTODISPLAYPREF = [];
++
++ //TRANS: %s is the number of new version
++ $migration->displayTitle(sprintf(__('Update to %s'), '9.3.3'));
++ $migration->setVersion('9.3.3');
++
++ // Create a dedicated token for rememberme process
++ if (!$DB->fieldExists('glpi_users', 'cookie_token')) {
++ $migration->addField('glpi_users', 'cookie_token', 'string', ['after' => 'api_token_date']);
++ $migration->addField('glpi_users', 'cookie_token_date', 'datetime', ['after' => 'cookie_token']);
++ }
++
++ // ************ Keep it at the end **************
++ $migration->executeMigration();
++
++ return $updateresult;
++}
+--
+2.20.1
+