Commit f2ade7fb authored by Andreas Fernandez's avatar Andreas Fernandez Committed by Christian Kuhn
Browse files

[TASK] Use unsafe but faster password hashing in `RecoveryCodeTest`

`RecoveryCodeTest` now uses a `NoopPasswordHash` implementation, that
uses sha1 internally. It's obviously not as secure as the til today
configured argon2 algorithm, but still fine for testing reasons, which
greatly improves the test runtime.

Resolves: #97788
Releases: main, 11.5
Change-Id: Ic7ee62f7dea3eedb2e792b88bec293e556454556
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/74929

Reviewed-by: Markus Klein's avatarMarkus Klein <markus.klein@typo3.org>
Reviewed-by: Oliver Klee's avatarOliver Klee <typo3-coding@oliverklee.de>
Reviewed-by: Stefan Bürk's avatarStefan Bürk <stefan@buerk.tech>
Reviewed-by: Christian Kuhn's avatarChristian Kuhn <lolli@schwarzbu.ch>
Tested-by: core-ci's avatarcore-ci <typo3@b13.com>
Tested-by: Oliver Klee's avatarOliver Klee <typo3-coding@oliverklee.de>
Tested-by: Stefan Bürk's avatarStefan Bürk <stefan@buerk.tech>
Tested-by: Christian Kuhn's avatarChristian Kuhn <lolli@schwarzbu.ch>
parent 7e0fe3e0
<?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\Tests\Fixtures\Crypto\PasswordHashing;
use TYPO3\CMS\Core\Core\Environment;
use TYPO3\CMS\Core\Crypto\PasswordHashing\PasswordHashInterface;
/**
* A special noop password "hashing" algorithm to be used in tests only - it is unsecure and optimized for speed.
*
* @internal
*/
class NoopPasswordHash implements PasswordHashInterface
{
protected const PREFIX = '$SHA1$';
public function __construct()
{
if (!Environment::getContext()->isTesting()) {
throw new \LogicException(
sprintf('The password hashing algorithm %s must not be used outside of testing context!', __CLASS__),
1655551062
);
}
}
public function checkPassword(string $plainPW, string $saltedHashPW): bool
{
return $this->getHashedPassword($plainPW) === $saltedHashPW;
}
public function isAvailable(): bool
{
return true;
}
public function getHashedPassword(string $password)
{
return self::PREFIX . sha1($password);
}
public function isHashUpdateNeeded(string $passString): bool
{
return false;
}
public function isValidSaltedPW(string $saltedPW): bool
{
return !strncmp(self::PREFIX, $saltedPW, strlen(self::PREFIX));
}
public static function registerNoopPasswordHash(): void
{
$GLOBALS['TYPO3_CONF_VARS']['SYS']['availablePasswordHashAlgorithms'][__CLASS__] = __CLASS__;
}
public static function unregisterNoopPasswordHash(): void
{
unset($GLOBALS['TYPO3_CONF_VARS']['SYS']['availablePasswordHashAlgorithms'][__CLASS__]);
}
}
......@@ -18,8 +18,8 @@ declare(strict_types=1);
namespace TYPO3\CMS\Core\Tests\Unit\Authentication\Mfa\Provider;
use TYPO3\CMS\Core\Authentication\Mfa\Provider\RecoveryCodes;
use TYPO3\CMS\Core\Crypto\PasswordHashing\Argon2iPasswordHash;
use TYPO3\CMS\Core\Crypto\PasswordHashing\BcryptPasswordHash;
use TYPO3\CMS\Core\Tests\Fixtures\Crypto\PasswordHashing\NoopPasswordHash;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
......@@ -30,22 +30,26 @@ class RecoveryCodesTest extends UnitTestCase
protected function setUp(): void
{
parent::setUp();
NoopPasswordHash::registerNoopPasswordHash();
$this->subject = GeneralUtility::makeInstance(RecoveryCodes::class, 'BE');
}
protected function tearDown(): void
{
NoopPasswordHash::unregisterNoopPasswordHash();
parent::tearDown();
}
/**
* @test
*/
public function generateRecoveryCodesTest(): void
{
$GLOBALS['TYPO3_CONF_VARS']['BE']['passwordHashing'] = [
'className' => Argon2iPasswordHash::class,
'options' => [
// Reduce default costs for quicker unit tests
'memory_cost' => 65536,
'time_cost' => 4,
'threads' => 2,
],
'className' => NoopPasswordHash::class,
'options' => [],
];
$codes = $this->subject->generateRecoveryCodes();
......@@ -54,7 +58,7 @@ class RecoveryCodesTest extends UnitTestCase
$plainCodes = array_keys($codes);
$hashedCodes = array_values($codes);
$hashInstance = (new Argon2iPasswordHash());
$hashInstance = (new NoopPasswordHash());
foreach ($hashedCodes as $key => $code) {
self::assertTrue($hashInstance->isValidSaltedPW($code));
......@@ -123,13 +127,8 @@ class RecoveryCodesTest extends UnitTestCase
public function verifyRecoveryCodeTest(): void
{
$GLOBALS['TYPO3_CONF_VARS']['BE']['passwordHashing'] = [
'className' => Argon2iPasswordHash::class,
'options' => [
// Reduce default costs for quicker unit tests
'memory_cost' => 65536,
'time_cost' => 4,
'threads' => 2,
],
'className' => NoopPasswordHash::class,
'options' => [],
];
$recoveryCode = '18742989';
......@@ -156,13 +155,7 @@ class RecoveryCodesTest extends UnitTestCase
public function verifyRecoveryCodeUsesTheCorrectHashInstanceTest(): void
{
$code = '18742989';
$argonOptionsSpeedup = [
// Reduce default costs for quicker unit tests
'memory_cost' => 65536,
'time_cost' => 4,
'threads' => 2,
];
$codes = [(new Argon2iPasswordHash($argonOptionsSpeedup))->getHashedPassword($code)];
$codes = [(new NoopPasswordHash())->getHashedPassword($code)];
// Ensure we have another default hash instance
$GLOBALS['TYPO3_CONF_VARS']['BE']['passwordHashing'] = [
......
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