[!!!][TASK] Remove lockHashKeyWords functionality 37/51437/4
authorBenni Mack <benni@typo3.org>
Thu, 26 Jan 2017 16:36:46 +0000 (17:36 +0100)
committerGeorg Ringer <georg.ringer@gmail.com>
Fri, 27 Jan 2017 11:01:03 +0000 (12:01 +0100)
The TYPO3 Core used the "useragent" to create a hashbase
by default to harden the session hijacking functionality.

This very very old feature adds a tiny bit of security on top,
however it has the drawback that users get logged out (of BE or FE)
if their browser updates (due to evergreen browsers or security
updates as the user agent string changes). This is very inconvenient
for websites that use a very long session time for logged in users
in the frontend (or backend) when using TYPO3 as a platform or
application.

It was originally concepted so it could be extended but there is no
hook to do so, and extending all classes does not really make a lot
of sense in the hierarchical PHP class structure.

Resolves: #79513
Releases: master
Change-Id: I78e58210da80c7c1544a644e8e10bc1f667b5bf1
Reviewed-on: https://review.typo3.org/51437
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Georg Ringer <georg.ringer@gmail.com>
Tested-by: Georg Ringer <georg.ringer@gmail.com>
typo3/sysext/core/Classes/Authentication/AbstractUserAuthentication.php
typo3/sysext/core/Configuration/DefaultConfiguration.php
typo3/sysext/core/Documentation/Changelog/master/Breaking-79513-RemovedSessionLockingBasedOnUseragent.rst [new file with mode: 0644]
typo3/sysext/core/ext_tables.sql
typo3/sysext/frontend/ext_tables.sql
typo3/sysext/install/Classes/Service/SilentConfigurationUpgradeService.php

index e276ee6..08c14b4 100644 (file)
@@ -230,14 +230,6 @@ abstract class AbstractUserAuthentication
     public $lockIP = 4;
 
     /**
-     * Keyword list (comma separated list with no spaces!)
-     * Each keyword indicates some information that can be included in a hash made to lock down user sessions.
-     * Configurable by $GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['lockHashKeyWords']
-     * @var string
-     */
-    public $lockHashKeyWords = 'useragent';
-
-    /**
      * @var string
      */
     public $warningEmail = '';
@@ -414,8 +406,6 @@ abstract class AbstractUserAuthentication
         if ($mode == 'get' && $this->getFallBack && $this->get_name) {
             $this->get_URL_ID = '&' . $this->get_name . '=' . $id;
         }
-        // Set session hashKey lock keywords from configuration; currently only 'useragent' can be used.
-        $this->lockHashKeyWords = $GLOBALS['TYPO3_CONF_VARS'][$this->loginType]['lockHashKeyWords'];
         // Make certain that NO user is set initially
         $this->user = null;
         // Set all possible headers that could ensure that the script is not cached on the client-side
@@ -905,7 +895,6 @@ abstract class AbstractUserAuthentication
             'ses_id' => $this->id,
             'ses_name' => $this->name,
             'ses_iplock' => $sessionIpLock,
-            'ses_hashlock' => $this->hashLockClause_getHashInt(),
             'ses_userid' => $tempuser[$this->userid_column],
             'ses_tstamp' => $GLOBALS['EXEC_TIME'],
             'ses_data' => ''
@@ -1080,10 +1069,6 @@ abstract class AbstractUserAuthentication
                 $queryBuilder->expr()->eq(
                     $this->session_table . '.ses_userid',
                     $queryBuilder->quoteIdentifier($this->user_table . '.' . $this->userid_column)
-                ),
-                $queryBuilder->expr()->eq(
-                    $this->session_table . '.ses_hashlock',
-                    $queryBuilder->createNamedParameter($this->hashLockClause_getHashInt(), \PDO::PARAM_INT)
                 )
             );
 
@@ -1232,32 +1217,6 @@ abstract class AbstractUserAuthentication
         return substr(md5($this->id . $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']), 0, 10);
     }
 
-    /**
-     * This returns the where-clause needed to lock a user to a hash integer
-     *
-     * @return string
-     * @access private
-     */
-    protected function hashLockClause()
-    {
-        return 'AND ' . $this->session_table . '.ses_hashlock=' . $this->hashLockClause_getHashInt();
-    }
-
-    /**
-     * Creates hash integer to lock user to. Depends on configured keywords
-     *
-     * @return int Hash integer
-     * @access private
-     */
-    protected function hashLockClause_getHashInt()
-    {
-        $hashStr = '';
-        if (GeneralUtility::inList($this->lockHashKeyWords, 'useragent')) {
-            $hashStr .= ':' . GeneralUtility::getIndpEnv('HTTP_USER_AGENT');
-        }
-        return GeneralUtility::md5int($hashStr);
-    }
-
     /*************************
      *
      * Session and Configuration Handling
index e8e0c54..ad6c2e0 100644 (file)
@@ -761,7 +761,6 @@ return [
         'lockSSL' => false,                                    // Boolean. If set, the backend can only be operated from an SSL-encrypted connection (https). A redirect to the SSL version of a URL will happen when a user tries to access non-https admin-urls
         'lockSSLPort' => 0,                                // Integer: Use a non-standard HTTPS port for lockSSL. Set this value if you use lockSSL and the HTTPS port of your webserver is not 443.
         'enabledBeUserIPLock' => true,                    // Boolean: If set, the User/Group TSconfig option 'option.lockToIP' is enabled.
-        'lockHashKeyWords' => 'useragent',                // Keyword list (Strings comma separated). Currently only "useragent"; If set, then the BE user session is locked to the value of HTTP_USER_AGENT. This lowers the risk of session hi-jacking. However in some cases (like during development) you might need to switch the user agent while keeping the session. In this case you can disable that feature (e.g. with a blank string).
         'cookieDomain' => '',                            // Same as <a href="#SYS-cookieDomain">$TYPO3_CONF_VARS['SYS']['cookieDomain']</a> but only for BE cookies. If empty, $TYPO3_CONF_VARS['SYS']['cookieDomain'] value will be used.
         'cookieName' => 'be_typo_user',                    // String: Set the name for the cookie used for the back-end user session
         'loginSecurityLevel' => '',                        // String: Keywords that determines the security level of login to the backend. "normal" means the password from the login form is sent in clear-text, "rsa" uses RSA password encryption (only if the rsaauth extension is installed).
@@ -1115,7 +1114,6 @@ return [
         'maxSessionDataSize' => 10000,        // Integer: Setting the maximum size (bytes) of frontend session data stored in the table fe_session_data. Set to zero (0) means no limit, but this is not recommended since it also disables a check that session data is stored only if a confirmed cookie is set.
         'cookieDomain' => '',        // Same as <a href="#SYS-cookieDomain">$TYPO3_CONF_VARS['SYS']['cookieDomain']</a> but only for FE cookies. If empty, $TYPO3_CONF_VARS['SYS']['cookieDomain'] value will be used.
         'cookieName' => 'fe_typo_user',        // String: Set the name for the cookie used for the front-end user session
-        'lockHashKeyWords' => 'useragent',        // Keyword list (Strings commaseparated). Currently only "useragent"; If set, then the FE user session is locked to the value of HTTP_USER_AGENT. This lowers the risk of session hi-jacking. However some cases (like payment gateways) might have to use the session cookie and in this case you will have to disable that feature (eg. with a blank string).
         'defaultUserTSconfig' => '',        // String (textarea). Enter lines of default frontend user/group TSconfig.
         'defaultTypoScript_constants' => '',        // String (textarea). Enter lines of default TypoScript, constants-field.
         'defaultTypoScript_constants.' => [],        // Lines of TS to include after a static template with the uid = the index in the array (Constants)
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Breaking-79513-RemovedSessionLockingBasedOnUseragent.rst b/typo3/sysext/core/Documentation/Changelog/master/Breaking-79513-RemovedSessionLockingBasedOnUseragent.rst
new file mode 100644 (file)
index 0000000..219472a
--- /dev/null
@@ -0,0 +1,57 @@
+.. include:: ../../Includes.txt
+
+=============================================================
+Breaking: #79513 - Removed session locking based on useragent
+=============================================================
+
+See :issue:`79513`
+
+Description
+===========
+
+When using session data or user-login functionality with TYPO3, the default configuration was to
+harden the session binding to the User Agent information sent by the HTTP request. If the user agent
+information does not match, the session gets renewed and the user gets logged out.
+
+The options `$TYPO3_CONF_VARS['FE']['lockHashKeyWords']` and `$TYPO3_CONF_VARS['BE']['lockHashKeyWords']`
+were set to "useragent" by default to use this additional session locking check.
+
+This case is especially problematic when having a larger website (e.g. a community platform) with
+100K frontend users and the session lifetime set to 6 months. After every security update of the
+browser or possibly a plugin, or if a version update is happening on Evergreen Browsers, then
+all users would get logged out, which is inconvenient.
+
+Based on the additional security level on top versus the user experience on the site, the "useragent"
+functionality has been dropped. Since the "lockHashKeyWords" options did only work on "useragent"
+and no other functionality was integrated, the option (and related, the database fields "ses_hashlock"
+as well) has been removed without substitution.
+
+
+Impact
+======
+
+The options `$TYPO3_CONF_VARS['FE']['lockHashKeyWords']` and `$TYPO3_CONF_VARS['BE']['lockHashKeyWords']`
+are removed automatically when hitting the install tool.
+
+The database fields 'fe_sessions.ses_hashlock' and 'be_sessions.ses_hashlock' have been removed.
+
+The public property `$lockHashKeyWords` of the PHP class `AbstractUserAuthentication` has been
+removed and will throw a PHP Notice when trying to access it.
+
+All other functionality related to sessions still works the same.
+
+
+Affected Installations
+======================
+
+Any installation using the configuration options for custom checks based on the session handling
+with third-party extensions, which is very unlikely.
+
+
+Migration
+=========
+
+The TYPO3 Install Tool removes the configuration option for existing installations. Using the
+"Database Comparison" view, it is possible to remove the fields from the database.
+
+.. index:: LocalConfiguration
\ No newline at end of file
index 811876f..fd44409 100644 (file)
@@ -39,7 +39,6 @@ CREATE TABLE be_sessions (
        ses_id varchar(32) DEFAULT '' NOT NULL,
        ses_name varchar(32) DEFAULT '' NOT NULL,
        ses_iplock varchar(39) DEFAULT '' NOT NULL,
-       ses_hashlock int(11) DEFAULT '0' NOT NULL,
        ses_userid int(11) unsigned DEFAULT '0' NOT NULL,
        ses_tstamp int(11) unsigned DEFAULT '0' NOT NULL,
        ses_data longblob,
index 620a408..848af2f 100644 (file)
@@ -63,7 +63,6 @@ CREATE TABLE fe_sessions (
        ses_id varchar(32) DEFAULT '' NOT NULL,
        ses_name varchar(32) DEFAULT '' NOT NULL,
        ses_iplock varchar(39) DEFAULT '' NOT NULL,
-       ses_hashlock int(11) DEFAULT '0' NOT NULL,
        ses_userid int(11) unsigned DEFAULT '0' NOT NULL,
        ses_tstamp int(11) unsigned DEFAULT '0' NOT NULL,
        ses_data blob,
index 8f364f9..3eea9f4 100644 (file)
@@ -84,7 +84,10 @@ class SilentConfigurationUpgradeService
         // #77411
         'SYS/caching/cacheConfigurations/extbase_typo3dbbackend_tablecolumns',
         // #77460
-        'SYS/caching/cacheConfigurations/extbase_typo3dbbackend_queries'
+        'SYS/caching/cacheConfigurations/extbase_typo3dbbackend_queries',
+        // #79513
+        'FE/lockHashKeyWords',
+        'BE/lockHashKeyWords'
     ];
 
     public function __construct(ConfigurationManager $configurationManager = null)