Skip to content

Commit 0b49501

Browse files
bmackohader
authored andcommitted
[SECURITY] Do not log sensitive data in authentication process
When having the debug logging activated for the authentication process, sensitive data is not being logged anymore. This change * removes password from being logged * hashes the cookie value processed for logging Resolves: #93925 Releases: master, 11.3, 10.4, 9.5 Change-Id: I8c610a72014de571ef52b4430c43f8d149b273d9 Security-Bulletin: CORE-SA-2021-012 Security-References: CVE-2021-32767 Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/69990 Tested-by: Oliver Hader <oliver.hader@typo3.org> Reviewed-by: Oliver Hader <oliver.hader@typo3.org>
1 parent 6f8d69d commit 0b49501

2 files changed

Lines changed: 39 additions & 11 deletions

File tree

typo3/sysext/core/Classes/Authentication/AbstractUserAuthentication.php

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ protected function setSessionCookie()
335335
);
336336
$message = $isRefreshTimeBasedCookie ? 'Updated Cookie: {session}, {domain}' : 'Set Cookie: {session}, {domain}';
337337
$this->logger->debug($message, [
338-
'session' => $sessionId,
338+
'session' => sha1($sessionId),
339339
'domain' => $cookieDomain,
340340
]);
341341
}
@@ -440,14 +440,14 @@ public function checkAuthentication()
440440
$authInfo = $this->getAuthInfoArray();
441441
// Get Login/Logout data submitted by a form or params
442442
$loginData = $this->getLoginFormData();
443-
$this->logger->debug('Login data', $loginData);
443+
$this->logger->debug('Login data', $this->removeSensitiveLoginDataForLoggingInfo($loginData));
444444
// Active logout (eg. with "logout" button)
445445
if ($loginData['status'] === LoginType::LOGOUT) {
446446
if ($this->writeStdLog) {
447447
// $type,$action,$error,$details_nr,$details,$data,$tablename,$recuid,$recpid
448448
$this->writelog(SystemLogType::LOGIN, SystemLogLoginAction::LOGOUT, SystemLogErrorClassification::MESSAGE, 2, 'User %s logged out', [$this->user['username']], '', 0, 0);
449449
}
450-
$this->logger->info('User logged out. Id: {session}', ['session' => $this->userSession->getIdentifier()]);
450+
$this->logger->info('User logged out. Id: {session}', ['session' => sha1($this->userSession->getIdentifier())]);
451451
$this->logoff();
452452
}
453453
// Determine whether we need to skip session update.
@@ -556,7 +556,7 @@ public function checkAuthentication()
556556
// Use 'auth' service to authenticate the user
557557
// If one service returns FALSE then authentication failed
558558
// a service might return 100 which means there's no reason to stop but the user can't be authenticated by that service
559-
$this->logger->debug('Auth user', $tempuser);
559+
$this->logger->debug('Auth user', $this->removeSensitiveLoginDataForLoggingInfo($tempuser, true));
560560
$subType = 'authUser' . $this->loginType;
561561

562562
/** @var AuthenticationService $serviceObj */
@@ -641,7 +641,7 @@ public function checkAuthentication()
641641
// Mark the current login attempt as failed
642642
if (empty($tempuserArr) && $activeLogin) {
643643
$this->logger->debug('Login failed', [
644-
'loginData' => $loginData
644+
'loginData' => $this->removeSensitiveLoginDataForLoggingInfo($loginData)
645645
]);
646646
} elseif (!empty($tempuserArr)) {
647647
$this->logger->debug('Login failed', [
@@ -861,7 +861,7 @@ public function enforceNewSessionId()
861861
*/
862862
public function logoff()
863863
{
864-
$this->logger->debug('logoff: ses_id = {session}', ['session' => $this->userSession->getIdentifier()]);
864+
$this->logger->debug('logoff: ses_id = {session}', ['session' => sha1($this->userSession->getIdentifier())]);
865865

866866
$_params = [];
867867
foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauth.php']['logoff_pre_processing'] ?? [] as $_funcRef) {
@@ -1094,7 +1094,7 @@ public function setSessionData($key, $data)
10941094
public function setAndSaveSessionData($key, $data)
10951095
{
10961096
$this->userSession->set($key, $data);
1097-
$this->logger->debug('setAndSaveSessionData: ses_id = {session}', ['session' => $this->userSession->getIdentifier()]);
1097+
$this->logger->debug('setAndSaveSessionData: ses_id = {session}', ['session' => sha1($this->userSession->getIdentifier())]);
10981098
$this->userSession = $this->userSessionManager->updateSession($this->userSession);
10991099
}
11001100

@@ -1138,7 +1138,7 @@ public function isActiveLogin(ServerRequestInterface $request): bool
11381138
*/
11391139
public function processLoginData($loginData)
11401140
{
1141-
$this->logger->debug('Login data before processing', $loginData);
1141+
$this->logger->debug('Login data before processing', $this->removeSensitiveLoginDataForLoggingInfo($loginData));
11421142
$subType = 'processLoginData' . $this->loginType;
11431143
$authInfo = $this->getAuthInfoArray();
11441144
$isLoginDataProcessed = false;
@@ -1156,11 +1156,39 @@ public function processLoginData($loginData)
11561156
}
11571157
if ($isLoginDataProcessed) {
11581158
$loginData = $processedLoginData;
1159-
$this->logger->debug('Processed login data', $processedLoginData);
1159+
$this->logger->debug('Processed login data', $this->removeSensitiveLoginDataForLoggingInfo($processedLoginData));
11601160
}
11611161
return $loginData;
11621162
}
11631163

1164+
/**
1165+
* Removes any sensitive data from the incoming data (either from loginData, processedLogin data
1166+
* or the user record from the DB).
1167+
*
1168+
* No type hinting is added because it might be possible that the incoming data is of any other type.
1169+
*
1170+
* @param mixed|array $data
1171+
* @param bool $isUserRecord
1172+
* @return mixed
1173+
*/
1174+
protected function removeSensitiveLoginDataForLoggingInfo($data, bool $isUserRecord = false)
1175+
{
1176+
if ($isUserRecord && is_array($data)) {
1177+
$fieldNames = ['uid', 'pid', 'tstamp', 'crdate', 'cruser_id', 'deleted', 'disabled', 'starttime', 'endtime', 'username', 'admin', 'usergroup', 'db_mountpoints', 'file_mountpoints', 'file_permissions', 'workspace_perms', 'lastlogin', 'workspace_id', 'category_perms'];
1178+
$data = array_intersect_key($data, array_combine($fieldNames, $fieldNames));
1179+
}
1180+
if (isset($data['uident'])) {
1181+
$data['uident'] = '********';
1182+
}
1183+
if (isset($data['uident_text'])) {
1184+
$data['uident_text'] = '********';
1185+
}
1186+
if (isset($data['password'])) {
1187+
$data['password'] = '********';
1188+
}
1189+
return $data;
1190+
}
1191+
11641192
/**
11651193
* Returns an info array which provides additional information for auth services
11661194
*

typo3/sysext/core/Classes/Session/UserSessionManager.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ public function createAnonymousSession(): UserSession
122122
*/
123123
public function createSessionFromStorage(string $sessionId): UserSession
124124
{
125-
$this->logger->debug('Fetch session with identifier {session}', ['session' => $sessionId]);
125+
$this->logger->debug('Fetch session with identifier {session}', ['session' => sha1($sessionId)]);
126126
$sessionRecord = $this->sessionBackend->get($sessionId);
127127
return UserSession::createFromRecord($sessionId, $sessionRecord);
128128
}
@@ -189,7 +189,7 @@ public function fixateAnonymousSession(UserSession $session, bool $isPermanent =
189189
public function elevateToFixatedUserSession(UserSession $session, int $userId, bool $isPermanent = false): UserSession
190190
{
191191
$sessionId = $session->getIdentifier();
192-
$this->logger->debug('Create session ses_id = {session}', ['session' => $sessionId]);
192+
$this->logger->debug('Create session ses_id = {session}', ['session' => sha1($sessionId)]);
193193
// Delete any session entry first
194194
$this->sessionBackend->remove($sessionId);
195195
// Re-create session entry

0 commit comments

Comments
 (0)