Commit 62b218c0 authored by Oliver Hader's avatar Oliver Hader Committed by Oliver Hader
Browse files

[SECURITY] Avoid storing plain session identifier in $USER->uc

`AbstractUserAuthentication::$uc['moduleSessionID']` still stored plain
session identifier, which has been replaced by corresponding HMAC.

Resolves: #93359
Releases: master, 11.1, 10.4, 9.5
Change-Id: I920b8d3b364c249d2ec3a6deb42e141e5a1b8ff7
Security-Bulletin: TYPO3-CORE-SA-2021-006
Security-References: CVE-2021-21339
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/68416

Tested-by: Oliver Hader's avatarOliver Hader <oliver.hader@typo3.org>
Reviewed-by: Oliver Hader's avatarOliver Hader <oliver.hader@typo3.org>
parent 19885966
......@@ -1257,8 +1257,12 @@ abstract class AbstractUserAuthentication implements LoggerAwareInterface
*/
public function pushModuleData($module, $data, $noSave = 0)
{
$sessionHash = GeneralUtility::hmac(
$this->id,
'core-session-hash'
);
$this->uc['moduleData'][$module] = $data;
$this->uc['moduleSessionID'][$module] = $this->id;
$this->uc['moduleSessionID'][$module] = $sessionHash;
if (!$noSave) {
$this->writeUC();
}
......@@ -1273,8 +1277,18 @@ abstract class AbstractUserAuthentication implements LoggerAwareInterface
*/
public function getModuleData($module, $type = '')
{
if ($type !== 'ses' || (isset($this->uc['moduleSessionID'][$module]) && $this->uc['moduleSessionID'][$module] == $this->id)) {
return $this->uc['moduleData'][$module];
$sessionHash = GeneralUtility::hmac(
$this->id,
'core-session-hash'
);
$sessionData = $this->uc['moduleData'][$module] ?? null;
$moduleSessionIdHash = $this->uc['moduleSessionID'][$module] ?? null;
if ($type !== 'ses'
|| $sessionData !== null && $moduleSessionIdHash === $sessionHash
// @todo Fallback for non-hashed values in `moduleSessionID`, remove for TYPO3 v11.5 LTS
|| $sessionData !== null && $moduleSessionIdHash === $this->id
) {
return $sessionData;
}
return null;
}
......
<?php
declare(strict_types = 1);
namespace TYPO3\CMS\Core\Tests\Functional\Authentication;
/*
* 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!
*/
use TYPO3\CMS\Core\Tests\Functional\Authentication\Fixtures\AnyUserAuthentication;
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
class AbstractUserAuthenticationTest extends FunctionalTestCase
{
/**
* @var string
*/
private $sessionId;
/**
* @var AnyUserAuthentication
*/
private $subject;
protected function setUp(): void
{
parent::setUp();
$GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'] = '12345';
$GLOBALS['TYPO3_CONF_VARS']['ANY']['lockIP'] = 0;
$GLOBALS['TYPO3_CONF_VARS']['ANY']['lockIPv6'] = 0;
$this->sessionId = bin2hex(random_bytes(20));
$this->subject = new AnyUserAuthentication($this->sessionId);
}
protected function tearDown(): void
{
unset($this->sessionId, $this->subject);
unset($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']);
parent::tearDown();
}
/**
* @test
*/
public function pushModuleDataDoesNotRevealPlainSessionId(): void
{
$this->subject->pushModuleData(self::class, true);
self::assertNotContains($this->sessionId, $this->subject->uc['moduleSessionID']);
}
/**
* @test
*/
public function getModuleDataResolvesHashedSessionId(): void
{
$this->subject->pushModuleData(self::class, true);
self::assertTrue($this->subject->getModuleData(self::class));
}
/**
* @test
*/
public function getModuleDataFallsBackToPlainSessionId(): void
{
$this->subject->uc['moduleData'][self::class] = true;
$this->subject->uc['moduleSessionID'][self::class] = $this->sessionId;
self::assertTrue($this->subject->getModuleData(self::class));
}
}
<?php
declare(strict_types = 1);
namespace TYPO3\CMS\Core\Tests\Functional\Authentication\Fixtures;
/*
* 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!
*/
use TYPO3\CMS\Core\Authentication\AbstractUserAuthentication;
class AnyUserAuthentication extends AbstractUserAuthentication
{
/**
* @var array
*/
public $uc = [];
/**
* @var string
*/
public $loginType = 'ANY';
public function __construct(string $sessionId)
{
parent::__construct();
$this->id = $sessionId;
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment