Skip to content

Commit

Permalink
[BUGFIX] Ensure uniqid calls use more_entropy
Browse files Browse the repository at this point in the history
Precision of `uniqid()` on Windows systems without passing
`$more_entropy=true` has only single-second-resolution which will
lead to non-unique ids on subsequent calls.

In order to mitigate this issue TYPO3 provides the function
`StringUtility::getUniqueId($prefix = '')` which calls
`uniqid()` with parameter `$more_entropy` always set to true.

Using `uniqid()`, especially with `$more_entropy` set to true,
is quite slow, but for the purposes TYPO3 is using it
(i.e. creating unique field names for backend forms, path
identifiers in some modules etc.) it is good enough and
another solution would not provide any measurable benefit.

Resolves: #91553
Releases: master, 10.4
Change-Id: Ib4443e72621eee6df2daf5bf23054e1a01325783
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/64652
Tested-by: TYPO3com <noreply@typo3.com>
Tested-by: Jörg Bösche <typo3@joergboesche.de>
Tested-by: Alexander Schnitzler <git@alexanderschnitzler.de>
Tested-by: Oliver Bartsch <bo@cedev.de>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Jörg Bösche <typo3@joergboesche.de>
Reviewed-by: Alexander Schnitzler <git@alexanderschnitzler.de>
Reviewed-by: Oliver Bartsch <bo@cedev.de>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
  • Loading branch information
Tizian Schmidlin authored and lolli42 committed Sep 4, 2020
1 parent d2d1169 commit e0c0b98
Show file tree
Hide file tree
Showing 18 changed files with 38 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
use TYPO3\CMS\Adminpanel\Controller\MainController;
use TYPO3\CMS\Adminpanel\Utility\StateUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\StringUtility;

/**
* PSR-15 Middleware to initialize the admin panel
Expand All @@ -45,7 +46,7 @@ class AdminPanelInitiator implements MiddlewareInterface
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
if (StateUtility::isActivatedForUser() && StateUtility::isOpen()) {
$request = $request->withAttribute('adminPanelRequestId', substr(md5(uniqid('', true)), 0, 13));
$request = $request->withAttribute('adminPanelRequestId', substr(md5(StringUtility::getUniqueId()), 0, 13));
$adminPanelController = GeneralUtility::makeInstance(
MainController::class
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
use TYPO3\CMS\Core\Type\Bitmask\Permission;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\HttpUtility;
use TYPO3\CMS\Core\Utility\StringUtility;
use TYPO3\CMS\Fluid\View\StandaloneView;

/**
Expand Down Expand Up @@ -264,7 +265,7 @@ protected function prepareContent(string $clientContext): void
// Go to DataHandler directly instead of FormEngine
if ($wInfo['saveAndClose'] ?? false) {
$urlParams = [];
$id = uniqid('NEW');
$id = StringUtility::getUniqueId('NEW');
parse_str($wInfo['params'], $urlParams);
$urlParams['data']['tt_content'][$id] = $urlParams['defVals']['tt_content'] ?? [];
$urlParams['data']['tt_content'][$id]['colPos'] = $this->colPos;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
use TYPO3\CMS\Core\Site\SiteFinder;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\MathUtility;
use TYPO3\CMS\Core\Utility\StringUtility;
use TYPO3\CMS\Fluid\View\StandaloneView;
use TYPO3Fluid\Fluid\View\ViewInterface;

Expand Down Expand Up @@ -364,7 +365,7 @@ protected function validateAndProcessIdentifier(bool $isNew, string $identifier,
$this->siteFinder->getSiteByIdentifier($identifier);
// Force this identifier to be unique
$originalIdentifier = $identifier;
$identifier = $identifier . '-' . str_replace('.', '', uniqid((string)random_int(0, mt_getrandmax()), true));
$identifier = StringUtility::getUniqueId($identifier . '-');
$message = sprintf(
$languageService->sL('LLL:EXT:backend/Resources/Private/Language/locallang_siteconfiguration.xlf:validation.identifierRenamed.message'),
$originalIdentifier,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ public function render()
if (is_array($group['header'])) {
$html[] = '<div id="' . $groupIdCollapsible . '" class="panel-collapse collapse" role="tabpanel">';
}
$checkboxId = uniqid($groupId);
$checkboxId = StringUtility::getUniqueId($groupId);
$title = htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.toggleall'));
$html[] = '<div class="table-responsive">';
$html[] = '<table class="table table-transparent table-hover">';
Expand Down
3 changes: 2 additions & 1 deletion typo3/sysext/backend/Tests/Unit/Routing/UriBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
use TYPO3\CMS\Backend\Routing\Route;
use TYPO3\CMS\Backend\Routing\Router;
use TYPO3\CMS\Backend\Routing\UriBuilder;
use TYPO3\CMS\Core\Utility\StringUtility;
use TYPO3\TestingFramework\Core\Unit\UnitTestCase;

/**
Expand Down Expand Up @@ -107,6 +108,6 @@ public function nonExistingRouteThrowsException()
$this->expectException(RouteNotFoundException::class);
$this->expectExceptionCode(1476050190);
$subject = new UriBuilder(new Router());
$subject->buildUriFromRoute(uniqid('any'));
$subject->buildUriFromRoute(StringUtility::getUniqueId('any'));
}
}
3 changes: 2 additions & 1 deletion typo3/sysext/core/Classes/Core/Bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
use TYPO3\CMS\Core\Service\DependencyOrderingService;
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\StringUtility;
use TYPO3\PharStreamWrapper\Behavior;
use TYPO3\PharStreamWrapper\Interceptor\ConjunctionInterceptor;
use TYPO3\PharStreamWrapper\Interceptor\PharMetaDataInterceptor;
Expand Down Expand Up @@ -75,7 +76,7 @@ public static function init(
ClassLoader $classLoader,
bool $failsafe = false
): ContainerInterface {
$requestId = substr(md5(uniqid('', true)), 0, 13);
$requestId = substr(md5(StringUtility::getUniqueId()), 0, 13);

static::initializeClassLoader($classLoader);
if (!Environment::isComposerMode() && ClassLoadingInformation::isClassLoadingInformationAvailable()) {
Expand Down
5 changes: 3 additions & 2 deletions typo3/sysext/core/Classes/Imaging/GraphicalFunctions.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\MathUtility;
use TYPO3\CMS\Core\Utility\PathUtility;
use TYPO3\CMS\Core\Utility\StringUtility;

/**
* Standard graphical functions
Expand Down Expand Up @@ -1934,7 +1935,7 @@ public function v5_blur($factor)
public function randomName()
{
GeneralUtility::mkdir_deep(Environment::getVarPath() . '/transient/');
return Environment::getVarPath() . '/transient/' . md5(uniqid('', true));
return Environment::getVarPath() . '/transient/' . md5(StringUtility::getUniqueId());
}

/**
Expand Down Expand Up @@ -2556,7 +2557,7 @@ public static function gifCompress($theFile, $type)

if (($type === 'IM' || !$type) && $gfxConf['processor_enabled'] && $gfxConf['processor_path_lzw']) {
// Use temporary file to prevent problems with read and write lock on same file on network file systems
$temporaryName = PathUtility::dirname($theFile) . '/' . md5(uniqid('', true)) . '.gif';
$temporaryName = PathUtility::dirname($theFile) . '/' . md5(StringUtility::getUniqueId()) . '.gif';
// Rename could fail, if a simultaneous thread is currently working on the same thing
if (@rename($theFile, $temporaryName)) {
$cmd = CommandUtility::imageMagickCommand(
Expand Down
3 changes: 2 additions & 1 deletion typo3/sysext/core/Classes/Resource/ResourceStorage.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
use TYPO3\CMS\Core\Utility\Exception\NotImplementedMethodException;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\PathUtility;
use TYPO3\CMS\Core\Utility\StringUtility;

/**
* A "mount point" inside the TYPO3 file handling.
Expand Down Expand Up @@ -2624,7 +2625,7 @@ protected function getUniqueName(FolderInterface $folder, $theFile, $dontCheckFo
if ($a <= $maxNumber) {
$insert = '_' . sprintf('%02d', $a);
} else {
$insert = '_' . substr(md5(uniqid('', true)), 0, 6);
$insert = '_' . substr(md5(StringUtility::getUniqueId()), 0, 6);
}
$theTestFile = $theTempFileBody . $insert . $theOrigExt;
// The destinations file
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
use TYPO3\CMS\Core\Resource\Search\QueryRestrictions\FolderRestriction;
use TYPO3\CMS\Core\Resource\Search\QueryRestrictions\SearchTermRestriction;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\StringUtility;

/**
* Represents an SQL query to search for files.
Expand Down Expand Up @@ -116,7 +117,7 @@ public static function createForSearchDemand(FileSearchDemand $searchDemand, Que
. preg_replace(
'/[^a-z0-9]/',
'',
uniqid($tableName . $fieldName, true)
StringUtility::getUniqueId($tableName . $fieldName)
)
]),
true
Expand Down
3 changes: 2 additions & 1 deletion typo3/sysext/core/Classes/Utility/File/BasicFileUtility.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use TYPO3\CMS\Core\Charset\CharsetConverter;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\PathUtility;
use TYPO3\CMS\Core\Utility\StringUtility;

/**
* Contains class with basic file management functions
Expand Down Expand Up @@ -107,7 +108,7 @@ public function getUniqueName($theFile, $theDest, $dontCheckForUnique = false)
$insert = '_' . sprintf('%02d', $a);
} else {
// .. then we try unique-strings...
$insert = '_' . substr(md5(uniqid('', true)), 0, $this->uniquePrecision);
$insert = '_' . substr(md5(StringUtility::getUniqueId()), 0, $this->uniquePrecision);
}
$theTestFile = $theTempFileBody . $insert . $theOrigExt;
$theDestFile = $theDest . '/' . $theTestFile;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,11 @@ public function getIconWithEXTSourceReferenceReturnsInstanceOfIconWithCorrectMar
*/
public function getIconWithInlineOptionReturnsCleanSvgMarkup()
{
$testFile = GeneralUtility::tempnam(uniqid('svg_') . '.svg');
$testFile = GeneralUtility::tempnam('svg_', '.svg');
$this->testFilesToDelete[] = $testFile;
$svgTestFileContent = '<?xml version="1.0" encoding="ISO-8859-1" standalone="no" ?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="#CD201F" d="M11 12l3-2v6H2v-6l3 2 3-2 3 2z"></path><script><![CDATA[ function alertMe() {} ]]></script></svg>';
file_put_contents($testFile, $svgTestFileContent);
$this->testFilesToDelete[] = GeneralUtility::tempnam(uniqid('svg_') . '.svg');
$this->testFilesToDelete[] = GeneralUtility::tempnam('svg_', '.svg');
$this->subject->prepareIconMarkup($this->icon, ['source' => $testFile]);
self::assertEquals('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="#CD201F" d="M11 12l3-2v6H2v-6l3 2 3-2 3 2z"/></svg>', $this->icon->getMarkup(SvgIconProvider::MARKUP_IDENTIFIER_INLINE));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

use TYPO3\CMS\Core\SingletonInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\StringUtility;
use TYPO3\CMS\Extbase\Security\Cryptography\HashService;
use TYPO3\CMS\Fluid\Core\Widget\Exception\WidgetContextNotFoundException;
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
Expand Down Expand Up @@ -92,7 +93,7 @@ public function get($ajaxWidgetId)
*/
public function store(WidgetContext $widgetContext)
{
$ajaxWidgetId = md5(uniqid(random_int(0, mt_getrandmax()), true));
$ajaxWidgetId = md5(StringUtility::getUniqueId());
$widgetContext->setAjaxWidgetIdentifier($ajaxWidgetId);
$this->widgetContexts[$ajaxWidgetId] = $widgetContext;
$this->storeWidgetContexts();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
use TYPO3\CMS\Core\Resource\ResourceFactory;
use TYPO3\CMS\Core\Resource\Security\FileNameValidator;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\StringUtility;
use TYPO3\CMS\Extbase\Domain\Model\AbstractFileFolder;
use TYPO3\CMS\Extbase\Domain\Model\FileReference as ExtbaseFileReference;
use TYPO3\CMS\Extbase\Error\Error;
Expand Down Expand Up @@ -243,8 +244,8 @@ protected function createFileReferenceFromFalFileObject(
$fileReference = $this->resourceFactory->createFileReferenceObject(
[
'uid_local' => $file->getUid(),
'uid_foreign' => uniqid('NEW_'),
'uid' => uniqid('NEW_'),
'uid_foreign' => StringUtility::getUniqueId('NEW_'),
'uid' => StringUtility::getUniqueId('NEW_'),
'crop' => null,
]
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

use TYPO3\CMS\Core\Page\PageRenderer;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\StringUtility;
use TYPO3\CMS\Extbase\Property\PropertyMapper;
use TYPO3\CMS\Fluid\ViewHelpers\Form\AbstractFormFieldViewHelper;
use TYPO3\CMS\Form\Domain\Runtime\FormRuntime;
Expand Down Expand Up @@ -94,7 +95,7 @@ public function render()
if ($this->hasArgument('id')) {
$id = $this->arguments['id'];
} else {
$id = 'field' . md5(uniqid());
$id = 'field' . md5(StringUtility::getUniqueId());
}

if (empty($placeholder)) {
Expand Down
5 changes: 3 additions & 2 deletions typo3/sysext/install/Classes/Controller/UpgradeController.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
use TYPO3\CMS\Core\Service\OpcodeCacheService;
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\StringUtility;
use TYPO3\CMS\Install\ExtensionScanner\Php\CodeStatistics;
use TYPO3\CMS\Install\ExtensionScanner\Php\GeneratorClassesResolver;
use TYPO3\CMS\Install\ExtensionScanner\Php\Matcher\ArrayDimensionMatcher;
Expand Down Expand Up @@ -738,7 +739,7 @@ public function extensionScannerScanFileAction(ServerRequestInterface $request):
$preparedMatches = [];
foreach ($matches as $match) {
$preparedHit = [];
$preparedHit['uniqueId'] = str_replace('.', '', uniqid((string)random_int(0, mt_getrandmax()), true));
$preparedHit['uniqueId'] = StringUtility::getUniqueId();
$preparedHit['message'] = $match['message'];
$preparedHit['line'] = $match['line'];
$preparedHit['indicator'] = $match['indicator'];
Expand Down Expand Up @@ -767,7 +768,7 @@ public function extensionScannerScanFileAction(ServerRequestInterface $request):
array_pop($version);
// something like "8.2" .. "8.7" .. "master"
$parsedRestFile['version'] = array_pop($version);
$parsedRestFile['uniqueId'] = str_replace('.', '', uniqid((string)random_int(0, mt_getrandmax()), true));
$parsedRestFile['uniqueId'] = StringUtility::getUniqueId();
$preparedHit['restFiles'][] = $parsedRestFile;
}
$preparedMatches[] = $preparedHit;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use TYPO3\CMS\Core\Resource\ProcessedFileRepository;
use TYPO3\CMS\Core\Resource\StorageRepository;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\StringUtility;
use TYPO3\CMS\Install\Service\Typo3tempFileService;
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;

Expand All @@ -41,7 +42,7 @@ class Typo3tempFileServiceTest extends FunctionalTestCase
protected function setUp(): void
{
parent::setUp();
$this->directoryName = uniqid('test');
$this->directoryName = StringUtility::getUniqueId('test');
$this->directoryPath = $this->instancePath . '/typo3temp/assets/' . $this->directoryName;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
use TYPO3\CMS\Core\Utility\DiffUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\MathUtility;
use TYPO3\CMS\Core\Utility\StringUtility;
use TYPO3\CMS\Workspaces\Domain\Model\CombinedRecord;
use TYPO3\CMS\Workspaces\Service\GridDataService;
use TYPO3\CMS\Workspaces\Service\HistoryService;
Expand Down Expand Up @@ -295,7 +296,7 @@ public function getRowDetails($parameter)
*/
protected function prepareFileReferenceDifferences(array $liveFileReferences, array $versionFileReferences, $useThumbnails = false)
{
$randomValue = uniqid('file');
$randomValue = StringUtility::getUniqueId('file');

$liveValues = [];
$versionValues = [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
use TYPO3\CMS\Core\Routing\UnableToLinkToPageException;
use TYPO3\CMS\Core\Site\SiteFinder;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\StringUtility;
use TYPO3\CMS\Core\Versioning\VersionState;
use TYPO3\CMS\Workspaces\Service\WorkspaceService;

Expand Down Expand Up @@ -213,7 +214,7 @@ public function buildUriForElement(string $table, int $uid, array $liveRecord =
*/
protected function compilePreviewKeyword(int $ttl = 172800, int $workspaceId = null): string
{
$keyword = md5(uniqid(microtime(), true));
$keyword = md5(StringUtility::getUniqueId());
GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable('sys_preview')
->insert(
Expand Down

0 comments on commit e0c0b98

Please sign in to comment.