CVE-2022-36105: Observable Discrepancy (CWE-203)
value: TYPO3 is an open source PHP based web content management system released under the GNU GPL. It has been discovered that observing response time during user authentication (backend and frontend) can be used to distinguish between existing and non-existing user accounts. Extension authors of 3rd party TYPO3 extensions providing a custom authentication service should check if the extension is affected by the described problem. Affected extensions must implement new `MimicServiceInterface::mimicAuthUser`, which simulates corresponding times regular processing would usually take. Update to TYPO3 version 7.6.58 ELTS, 8.7.48 ELTS, 9.5.37 ELTS, 10.4.32 or 11.5.16 that fix this problem. There are no known workarounds for this issue.
CWE description: The product behaves differently or sends different responses under different circumstances in a way that is observable to an unauthorized actor, which exposes security-relevant information about the state of the product, such as whether a particular operation was successful or not.
CVSS v3 base score: 5.3
Published: 2022-09-13T18:15Z
Repository: https://github.com/TYPO3/typo3
Language: PHP
Files changed: typo3/sysext/core/Classes/Authentication/AbstractUserAuthentication.php, typo3/sysext/core/Classes/Authentication/AuthenticationService.php, typo3/sysext/core/Classes/Authentication/MimicServiceInterface.php
Commit date: 2022-09-13 10:08:44 +0200
Commit message: [SECURITY] Mitigate timing discrepancies during user authentication

Observing response time during user authentication can be used to
distinguish between existing and non-existing user accounts. This
change introduces `MimicServiceInterface::mimicAuthUser` -  to be
implemented by 3rd party authentication services - which simulates
corresponding times regular processing would usually take.

Resolves: #98217
Releases: main, 11.5, 10.4
Change-Id: I143ae0d3877dffe6f2decbb3f0cf8c9d9cb6ca0b
Security-Bulletin: TYPO3-CORE-SA-2022-007
Security-References: CVE-2022-36105
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/75716
Tested-by: Oliver Hader <oliver.hader@typo3.org>
Reviewed-by: Oliver Hader <oliver.hader@typo3.org>

Diff: diff --git a/typo3/sysext/core/Classes/Authentication/AbstractUserAuthentication.php b/typo3/sysext/core/Classes/Authentication/AbstractUserAuthentication.php
index b8b8b7d4fa1d..8626da05e74d 100644
--- a/typo3/sysext/core/Classes/Authentication/AbstractUserAuthentication.php
+++ b/typo3/sysext/core/Classes/Authentication/AbstractUserAuthentication.php
@@ -577,10 +577,19 @@ abstract class AbstractUserAuthentication implements LoggerAwareInterface
                 if ($authenticated) {
                     // Leave foreach() because a user is authenticated
                     break;
                 }
             }
+        // mimic user authentication to mitigate observable timing discrepancies
+        // @link https://cwe.mitre.org/data/definitions/208.html
+        } elseif ($activeLogin) {
+            $subType = 'authUser' . $this->loginType;
+            foreach ($this->getAuthServices($subType, $loginData, $authInfo) as $serviceObj) {
+                if ($serviceObj instanceof MimicServiceInterface && $serviceObj->mimicAuthUser() === false) {
+                    break;
+                }
+            }
         }
 
         // If user is authenticated a valid user is in $tempuser
         if ($authenticated) {
             // Insert session record if needed:
diff --git a/typo3/sysext/core/Classes/Authentication/AuthenticationService.php b/typo3/sysext/core/Classes/Authentication/AuthenticationService.php
index 4f99a8197f01..357a3c040866 100644
--- a/typo3/sysext/core/Classes/Authentication/AuthenticationService.php
+++ b/typo3/sysext/core/Classes/Authentication/AuthenticationService.php
@@ -26,11 +26,11 @@ use TYPO3\CMS\Core\TimeTracker\TimeTracker;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 
 /**
  * Authentication services class
  */
-class AuthenticationService extends AbstractAuthenticationService
+class AuthenticationService extends AbstractAuthenticationService implements MimicServiceInterface
 {
     /**
      * Process the submitted credentials.
      * In this case hash the clear text password if it has been submitted.
      *
@@ -172,10 +172,26 @@ class AuthenticationService extends AbstractAuthenticationService
         // Responsible, authentication ok. Log successful login and return 'auth ok, do NOT check other services'
         $this->writeLogMessage($this->pObj->loginType . ' Authentication successful for username \'%s\'', $submittedUsername);
         return 200;
     }
 
+    /**
+     * Mimics password hashing for invalid authentication requests to mitigate
+     * @link https://cwe.mitre.org/data/definitions/208.html: CWE-208: Observable Timing Discrepancy
+     */
+    public function mimicAuthUser(): bool
+    {
+        try {
+            $hashFactory = GeneralUtility::makeInstance(PasswordHashFactory::class);
+            $defaultHashInstance = $hashFactory->getDefaultHashInstance($this->pObj->loginType);
+            $defaultHashInstance->getHashedPassword(random_bytes(10));
+        } catch (\Exception) {
+            // no further processing here
+        }
+        return false;
+    }
+
     /**
      * Method updates a FE/BE user record - in this case a new password string will be set.
      *
      * @param string $table Database table of this user, usually 'be_users' or 'fe_users'
      * @param int $uid uid of user record that will be updated
diff --git a/typo3/sysext/core/Classes/Authentication/MimicServiceInterface.php b/typo3/sysext/core/Classes/Authentication/MimicServiceInterface.php
new file mode 100644
index 000000000000..07f33cc665c5
--- /dev/null
+++ b/typo3/sysext/core/Classes/Authentication/MimicServiceInterface.php
@@ -0,0 +1,35 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+namespace TYPO3\CMS\Core\Authentication;
+
+interface MimicServiceInterface
+{
+    /**
+     * Mimics user authentication for known invalid authentication requests. This method can be used
+     * to mitigate timing discrepancies for invalid authentication attempts, which can be used for
+     * user enumeration.
+     *
+     * Authentication services can implement this method to simulate(!) corresponding processes that
+     * would be processed during valid requests - e.g. perform password hashing (timing) or call
+     * remote services (network latency).
+     *
+     * @return bool whether other services shall continue
+     * @link https://cwe.mitre.org/data/definitions/208.html: CWE-208: Observable Timing Discrepancy
+     */
+    public function mimicAuthUser(): bool;
+}

Vulnerable code: class AuthenticationService extends AbstractAuthenticationService
Fixed code:         // mimic user authentication to mitigate observable timing discrepancies
        // @link https://cwe.mitre.org/data/definitions/208.html
        } elseif ($activeLogin) {
            $subType = 'authUser' . $this->loginType;
            foreach ($this->getAuthServices($subType, $loginData, $authInfo) as $serviceObj) {
                if ($serviceObj instanceof MimicServiceInterface && $serviceObj->mimicAuthUser() === false) {
                    break;
                }
            }
class AuthenticationService extends AbstractAuthenticationService implements MimicServiceInterface
    /**
     * Mimics password hashing for invalid authentication requests to mitigate
     * @link https://cwe.mitre.org/data/definitions/208.html: CWE-208: Observable Timing Discrepancy
     */
    public function mimicAuthUser(): bool
    {
        try {
            $hashFactory = GeneralUtility::makeInstance(PasswordHashFactory::class);
            $defaultHashInstance = $hashFactory->getDefaultHashInstance($this->pObj->loginType);
            $defaultHashInstance->getHashedPassword(random_bytes(10));
        } catch (\Exception) {
            // no further processing here
        }
        return false;
    }

<?php

declare(strict_types=1);

/*
 * This file is part of the TYPO3 CMS project.
 *
 * It is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License, either version 2
 * of the License, or any later version.
 *
 * For the full copyright and license information, please read the
 * LICENSE.txt file that was distributed with this source code.
 *
 * The TYPO3 project - inspiring people to share!
 */

namespace TYPO3\CMS\Core\Authentication;

interface MimicServiceInterface
{
    /**
     * Mimics user authentication for known invalid authentication requests. This method can be used
     * to mitigate timing discrepancies for invalid authentication attempts, which can be used for
     * user enumeration.
     *
     * Authentication services can implement this method to simulate(!) corresponding processes that
     * would be processed during valid requests - e.g. perform password hashing (timing) or call
     * remote services (network latency).
     *
     * @return bool whether other services shall continue
     * @link https://cwe.mitre.org/data/definitions/208.html: CWE-208: Observable Timing Discrepancy
     */
    public function mimicAuthUser(): bool;
}