Commit fa817a7e authored by Tymoteusz Motylewski's avatar Tymoteusz Motylewski Committed by Markus Klein
Browse files

[BUGFIX] Add more entropy to uniqid

uniqid() generates values based on current time,
subsequent calls may return the same value on a fast machine.

On Windows it's even worse, as uniqid()
has single-second-resolution out of the box.

Right now it is used in many places in the core,
also for creating temporary identifiers
for newly created records (in the datahandler).

The solution is to add a second parameter to
all calls (which adds more entropy).
see http://php.net/manual/en/function.uniqid.php

To make code consistent, this change adds the
 second parameter to all occurences of uniqid.

Resolves: #59701
Resolves: #58602
Resolves: #59055
Releases: master, 6.2
Change-Id: Id791556d45b4289d75411ff19ae050144fbfe51b
Reviewed-on: http://review.typo3.org/30948


Reviewed-by: Anja Leichsenring's avatarAnja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: Anja Leichsenring's avatarAnja Leichsenring <aleichsenring@ab-softlab.de>
Reviewed-by: Wouter Wolters's avatarWouter Wolters <typo3@wouterwolters.nl>
Tested-by: Wouter Wolters's avatarWouter Wolters <typo3@wouterwolters.nl>
Reviewed-by: Stefan Froemken's avatarStefan Froemken <froemken@gmail.com>
Tested-by: Stefan Froemken's avatarStefan Froemken <froemken@gmail.com>
Reviewed-by: default avatarMarkus Klein <klein.t3@reelworx.at>
Tested-by: default avatarMarkus Klein <klein.t3@reelworx.at>
parent 53ba0801
......@@ -136,7 +136,7 @@ class AjaxLoginHandler {
*/
public function getChallenge(array $parameters, \TYPO3\CMS\Core\Http\AjaxRequestHandler $parent) {
session_start();
$_SESSION['login_challenge'] = md5(uniqid('') . getmypid());
$_SESSION['login_challenge'] = md5(uniqid('', TRUE) . getmypid());
session_commit();
$parent->addContent('challenge', $_SESSION['login_challenge']);
$parent->setContentFormat('json');
......
......@@ -470,7 +470,7 @@ class BackendController {
'PATH_typo3' => $pathTYPO3,
'PATH_typo3_enc' => rawurlencode($pathTYPO3),
'username' => htmlspecialchars($GLOBALS['BE_USER']->user['username']),
'uniqueID' => GeneralUtility::shortMD5(uniqid('')),
'uniqueID' => GeneralUtility::shortMD5(uniqid('', TRUE)),
'securityLevel' => $this->loginSecurityLevel,
'TYPO3_mainDir' => TYPO3_mainDir,
'pageModule' => $pageModule,
......
......@@ -728,7 +728,7 @@ class EditDocumentController {
// 'new'
$trData->fetchRecord($table, $theUid, $cmd == 'new' ? 'new' : '');
$rec = reset($trData->regTableItems_data);
$rec['uid'] = $cmd == 'new' ? uniqid('NEW') : $theUid;
$rec['uid'] = $cmd == 'new' ? uniqid('NEW', TRUE) : $theUid;
if ($cmd == 'new') {
$rec['pid'] = $theUid == 'prev' ? $thePrevUid : $theUid;
}
......
......@@ -673,7 +673,7 @@ class PageLayoutController {
reset($trData->regTableItems_data);
$rec = current($trData->regTableItems_data);
if ($uidVal == 'new') {
$new_unique_uid = uniqid('NEW');
$new_unique_uid = uniqid('NEW', TRUE);
$rec['uid'] = $new_unique_uid;
$rec['pid'] = (int)$ex_pid ?: $this->id;
$recordAccess = TRUE;
......
......@@ -157,7 +157,7 @@ class DataPreprocessor {
$GLOBALS['TYPO3_DB']->sql_free_result($res);
}
// Finally, call renderRecord:
$this->renderRecord($table, uniqid('NEW'), $id, $newRow);
$this->renderRecord($table, uniqid('NEW', TRUE), $id, $newRow);
} else {
$id = (int)$id;
// Fetch database values
......
......@@ -291,7 +291,7 @@ class FlexElement extends AbstractFormElement {
$formPrefix . '[' . $key . '][el][' . $idTagPrefix . '-form]', $level + 1,
$idTagPrefix);
// Makes a "Add new" link:
$var = uniqid('idvar');
$var = str_replace('.', '', uniqid('idvar', TRUE));
$replace = 'replace(/' . $idTagPrefix . '-/g,"' . $idTagPrefix . '-"+' . $var . '+"-")';
$replace .= '.replace(/(tceforms-(datetime|date)field-)/g,"$1" + (new Date()).getTime())';
$onClickInsert = 'var ' . $var . ' = "' . 'idx"+(new Date()).getTime();'
......
......@@ -1521,7 +1521,7 @@ class InlineElement {
if (!empty($foreignTranslationPointerField)) {
$record[$foreignTranslationPointerField] = $record['uid'];
}
$newId = uniqid('NEW');
$newId = uniqid('NEW', TRUE);
$record['uid'] = $newId;
$record['pid'] = $this->inlineFirstPid;
$relatedRecords['records'][$newId] = $record;
......@@ -1764,7 +1764,7 @@ class InlineElement {
*/
public function getNewRecord($pid, $table) {
$rec = $this->getRecord($pid, $table, $pid, 'new');
$rec['uid'] = uniqid('NEW');
$rec['uid'] = uniqid('NEW', TRUE);
$rec['pid'] = $this->getNewRecordPid($table, $pid);
return $rec;
}
......
......@@ -61,41 +61,42 @@ class InputElement extends AbstractFormElement {
if (isset($config['range']['upper'])) {
$dateRange .= ' upper-' . (int)$config['range']['upper'];
}
$inputId = uniqid('tceforms-' . $class . 'field-');
$inputId = uniqid('tceforms-' . $class . 'field-', TRUE);
$cssClasses[] = 'tceforms-textfield tceforms-' . $class . 'field' . $dateRange;
$fieldAppendix = IconUtility::getSpriteIcon('actions-edit-pick-date', array(
'style' => 'cursor:pointer;',
'id' => 'picker-' . $inputId
));
} elseif (in_array('timesec', $evalList)) {
$inputId = uniqid('tceforms-timesecfield-');
$inputId = uniqid('tceforms-timesecfield-', TRUE);
$cssClasses[] = 'tceforms-textfield tceforms-timesecfield';
} elseif (in_array('year', $evalList)) {
$inputId = uniqid('tceforms-yearfield-');
$inputId = uniqid('tceforms-yearfield-', TRUE);
$cssClasses[] = 'tceforms-textfield tceforms-yearfield';
} elseif (in_array('time', $evalList)) {
$inputId = uniqid('tceforms-timefield-');
$inputId = uniqid('tceforms-timefield-', TRUE);
$cssClasses[] = 'tceforms-textfield tceforms-timefield';
} elseif (in_array('int', $evalList)) {
$inputId = uniqid('tceforms-intfield-');
$inputId = uniqid('tceforms-intfield-', TRUE);
$cssClasses[] = 'tceforms-textfield tceforms-intfield';
} elseif (in_array('double2', $evalList)) {
$inputId = uniqid('tceforms-double2field-');
$inputId = uniqid('tceforms-double2field-', TRUE);
$cssClasses[] = 'tceforms-textfield tceforms-double2field';
} else {
$inputId = uniqid('tceforms-textfield-');
$inputId = uniqid('tceforms-textfield-', TRUE);
$cssClasses[] = 'tceforms-textfield';
if ($checkboxIsset === FALSE) {
$config['checkbox'] = '';
}
}
if (isset($config['wizards']['link'])) {
$inputId = uniqid('tceforms-linkfield-');
$inputId = uniqid('tceforms-linkfield-', TRUE);
$cssClasses[] = 'tceforms-textfield tceforms-linkfield';
} elseif (isset($config['wizards']['color'])) {
$inputId = uniqid('tceforms-colorfield-');
$inputId = uniqid('tceforms-colorfield-', TRUE);
$cssClasses[] = 'tceforms-textfield tceforms-colorfield';
}
$inputId = str_replace('.', '', $inputId);
if ($this->formEngine->renderReadonly || $config['readOnly']) {
$itemFormElValue = $additionalInformation['itemFormElValue'];
if (in_array('date', $evalList)) {
......
......@@ -176,7 +176,7 @@ class SelectElement extends AbstractFormElement {
: $size;
$sOnChange = implode('', $PA['fieldChangeFunc']);
$multiSelectId = uniqid('tceforms-multiselect-');
$multiSelectId = str_replace('.', '', uniqid('tceforms-multiselect-', TRUE));
$itemsToSelect = '
<select data-relatedfieldname="' . htmlspecialchars($PA['itemFormElName']) . '" data-exclusivevalues="'
. htmlspecialchars($config['exclusiveKeys']) . '" id="' . $multiSelectId . '" name="' . $PA['itemFormElName'] . '_sel"'
......@@ -473,7 +473,7 @@ class SelectElement extends AbstractFormElement {
if ($config['iconsInOptionTags']) {
$classesForSelectTag[] = 'icon-select';
}
$item .= '<select' . $selectedStyle . ' id="' . uniqid('tceforms-select-') . '" name="' . $PA['itemFormElName'] . '"' . $this->formEngine->insertDefStyle('select', implode(' ', $classesForSelectTag)) . ($size ? ' size="' . $size . '"' : '') . ' onchange="' . htmlspecialchars($sOnChange) . '"' . $PA['onFocus'] . $disabled . '>';
$item .= '<select' . $selectedStyle . ' id="' . str_replace('.', '', uniqid('tceforms-select-', TRUE)) . '" name="' . $PA['itemFormElName'] . '"' . $this->formEngine->insertDefStyle('select', implode(' ', $classesForSelectTag)) . ($size ? ' size="' . $size . '"' : '') . ' onchange="' . htmlspecialchars($sOnChange) . '"' . $PA['onFocus'] . $disabled . '>';
$item .= implode('', $opt);
$item .= '</select>';
// Create icon table:
......@@ -561,7 +561,7 @@ class SelectElement extends AbstractFormElement {
$selIcon = IconUtility::getSpriteIcon('empty-empty');
}
// Compile row:
$rowId = uniqid('select_checkbox_row_');
$rowId = str_replace('.', '', uniqid('select_checkbox_row_', TRUE));
$onClickCell = $this->formEngine->elName(($PA['itemFormElName'] . '[' . $c . ']')) . '.checked=!' . $this->formEngine->elName(($PA['itemFormElName'] . '[' . $c . ']')) . '.checked;';
$onClick = 'this.attributes.getNamedItem("class").nodeValue = ' . $this->formEngine->elName(($PA['itemFormElName'] . '[' . $c . ']')) . '.checked ? "c-selectedItem" : "c-unselectedItem";';
$setAll[] = $this->formEngine->elName(($PA['itemFormElName'] . '[' . $c . ']')) . '.checked=1;';
......@@ -715,7 +715,7 @@ class SelectElement extends AbstractFormElement {
$size = $config['autoSizeMax']
? MathUtility::forceIntegerInRange(count($selItems) + 1, MathUtility::forceIntegerInRange($size, 1), $config['autoSizeMax'])
: $size;
$selectBox = '<select id="' . uniqid($cssPrefix) . '" name="' . $PA['itemFormElName'] . '[]"'
$selectBox = '<select id="' . str_replace('.', '', uniqid($cssPrefix, TRUE)) . '" name="' . $PA['itemFormElName'] . '[]"'
. $this->formEngine->insertDefStyle('select', $cssPrefix) . ($size ? ' size="' . $size . '"' : '')
. ' multiple="multiple" onchange="' . htmlspecialchars($sOnChange) . '"' . $PA['onFocus']
. $selector_itemListStyle . $disabled . '>
......
......@@ -188,7 +188,7 @@ class TextElement extends AbstractFormElement {
}
$textOnChange = implode('', $additionalInformation['fieldChangeFunc']);
$item .= '
<textarea ' . 'id="' . uniqid('tceforms-textarea-') . '" ' . 'name="' . $additionalInformation['itemFormElName']
<textarea ' . 'id="' . str_replace('.', '', uniqid('tceforms-textarea-', TRUE)) . '" ' . 'name="' . $additionalInformation['itemFormElName']
. '"' . $formWidthText . $class . ' ' . 'rows="' . $rows . '" ' . 'wrap="' . $wrap . '" ' . 'onchange="'
. htmlspecialchars($textOnChange) . '"' . $this->formEngine->getPlaceholderAttribute($table, $field, $config, $row)
. $additionalInformation['onFocus'] . '>' . GeneralUtility::formatForTextarea($additionalInformation['itemFormElValue']) . '</textarea>';
......
......@@ -1557,7 +1557,7 @@ class FormEngine {
. (in_array($lArr['ISOcode'], $selectedLanguage) ? ' selected="selected"' : '') . '>'
. htmlspecialchars($lArr['title']) . '</option>';
}
$output = '<select id="' . uniqid('tceforms-multiselect-')
$output = '<select id="' . str_replace('.', '', uniqid('tceforms-multiselect-', TRUE))
. ' class="tceforms-select tceforms-multiselect tceforms-flexlangmenu" name="' . $elName . '[]"'
. ($multi ? ' multiple="multiple" size="' . count($languages) . '"' : '') . '>' . implode('', $opt)
. '</select>';
......@@ -2293,7 +2293,7 @@ class FormEngine {
: $params['size'];
if (!$selector) {
$isMultiple = $params['maxitems'] != 1 && $params['size'] != 1;
$selector = '<select id="' . uniqid('tceforms-multiselect-') . '" '
$selector = '<select id="' . str_replace('.', '', uniqid('tceforms-multiselect-', TRUE)) . '" '
. ($params['noList'] ? 'style="display: none"' : 'size="' . $sSize . '"' . $this->insertDefStyle('group', 'tceforms-multiselect'))
. ($isMultiple ? ' multiple="multiple"' : '')
. ' name="' . $fName . '_list" ' . $onFocus . $params['style'] . $disabled . '>' . implode('', $opt)
......@@ -2752,7 +2752,7 @@ class FormEngine {
$assignValue = $this->elName($itemName) . '.value=this.options[this.selectedIndex].value';
}
$sOnChange = $assignValue . ';this.blur();this.selectedIndex=0;' . implode('', $fieldChangeFunc);
$outArr[] = '<select id="' . uniqid('tceforms-select-')
$outArr[] = '<select id="' . str_replace('.', '', uniqid('tceforms-select-', TRUE))
. '" class="tceforms-select tceforms-wizardselect" name="_WIZARD' . $fName . '" onchange="'
. htmlspecialchars($sOnChange) . '">' . implode('', $opt) . '</select>';
break;
......
......@@ -458,8 +458,8 @@ class PageLayoutView extends \TYPO3\CMS\Recordlist\RecordList\AbstractDatabaseRe
$content[$key] .= '">';
// Add new content at the top most position
$content[$key] .= '
<div class="t3-page-ce" id="' . uniqid() . '">
<div class="t3-page-ce-dropzone" id="colpos-' . $key . '-' . 'page-' . $id . '-' . uniqid() . '">
<div class="t3-page-ce" id="' . str_replace('.', '', uniqid('', TRUE)) . '">
<div class="t3-page-ce-dropzone" id="colpos-' . $key . '-' . 'page-' . $id . '-' . uniqid('', TRUE) . '">
<div class="t3-page-ce-wrapper-new-ce">
<a href="#" onclick="' . htmlspecialchars($this->newContentElementOnClick($id, $key, $lP))
. '" title="' . $this->getLanguageService()->getLL('newRecordHere', TRUE) . '">'
......@@ -489,7 +489,7 @@ class PageLayoutView extends \TYPO3\CMS\Recordlist\RecordList\AbstractDatabaseRe
$editUidList .= $row['uid'] . ',';
$disableMoveAndNewButtons = $this->defLangBinding && $lP > 0;
if (!$this->tt_contentConfig['languageMode']) {
$singleElementHTML .= '<div class="t3-page-ce-dragitem" id="' . uniqid() . '">';
$singleElementHTML .= '<div class="t3-page-ce-dragitem" id="' . str_replace('.', '', uniqid('', TRUE)) . '">';
}
$singleElementHTML .= $this->tt_content_drawHeader(
$row,
......@@ -513,7 +513,7 @@ class PageLayoutView extends \TYPO3\CMS\Recordlist\RecordList\AbstractDatabaseRe
$singleElementHTML .= '<div class="t3-page-ce">';
}
$singleElementHTML .= '<div class="t3-page-ce-dropzone" id="colpos-' . $key . '-' . 'page-' . $id .
'-' . uniqid() . '">';
'-' . str_replace('.', '', uniqid('', TRUE)) . '">';
// Add icon "new content element below"
if (!$disableMoveAndNewButtons) {
// New content element:
......
......@@ -147,7 +147,7 @@ class FileBackend extends \TYPO3\CMS\Core\Cache\Backend\SimpleFileBackend implem
throw new \RuntimeException(sprintf('Cannot add or modify cache entry because the backend of cache "%s" is frozen.', $this->cacheIdentifier), 1323344192);
}
$this->remove($entryIdentifier);
$temporaryCacheEntryPathAndFilename = $this->cacheDirectory . uniqid() . '.temp';
$temporaryCacheEntryPathAndFilename = $this->cacheDirectory . uniqid('', TRUE) . '.temp';
$lifetime = $lifetime === NULL ? $this->defaultLifetime : $lifetime;
$expiryTime = $lifetime === 0 ? 0 : $GLOBALS['EXEC_TIME'] + $lifetime;
$metaData = str_pad($expiryTime, self::EXPIRYTIME_LENGTH) . implode(' ', $tags) . str_pad(strlen($data), self::DATASIZE_DIGITS);
......
......@@ -475,7 +475,7 @@ class RedisBackend extends \TYPO3\CMS\Core\Cache\Backend\AbstractBackend impleme
protected function removeIdentifierEntriesAndRelations(array $identifiers, array $tags) {
// Set a temporary entry which holds all identifiers that need to be removed from
// the tag to identifiers sets
$uniqueTempKey = 'temp:' . uniqId();
$uniqueTempKey = 'temp:' . uniqid('', TRUE);
$prefixedKeysToDelete = array($uniqueTempKey);
$prefixedIdentifierToTagsKeysToDelete = array();
foreach ($identifiers as $identifier) {
......
......@@ -234,7 +234,7 @@ class SimpleFileBackend extends \TYPO3\CMS\Core\Cache\Backend\AbstractBackend im
if ($entryIdentifier === '') {
throw new \InvalidArgumentException('The specified entry identifier must not be empty.', 1334756736);
}
$temporaryCacheEntryPathAndFilename = $this->cacheDirectory . uniqid() . '.temp';
$temporaryCacheEntryPathAndFilename = $this->cacheDirectory . uniqid('', TRUE) . '.temp';
$result = file_put_contents($temporaryCacheEntryPathAndFilename, $data);
\TYPO3\CMS\Core\Utility\GeneralUtility::fixPermissions($temporaryCacheEntryPathAndFilename);
if ($result === FALSE) {
......
......@@ -69,7 +69,7 @@ class Bootstrap {
* @var string Application context
*/
protected function __construct($applicationContext) {
$this->requestId = uniqid();
$this->requestId = substr(md5(uniqid('', TRUE)), 0, 13);
$this->applicationContext = new ApplicationContext($applicationContext);
}
......
......@@ -3001,7 +3001,7 @@ class DataHandler {
$row = BackendUtility::getRecordWSOL($table, $uid);
if (is_array($row)) {
// Initializing:
$theNewID = uniqid('NEW');
$theNewID = uniqid('NEW', TRUE);
$enableField = isset($GLOBALS['TCA'][$table]['ctrl']['enablecolumns']) ? $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled'] : '';
$headerField = $GLOBALS['TCA'][$table]['ctrl']['label'];
// Getting default data:
......@@ -3248,7 +3248,7 @@ class DataHandler {
* @return integer Returns the new ID of the record (if applicable)
*/
public function insertNewCopyVersion($table, $fieldArray, $realPid) {
$id = uniqid('NEW');
$id = uniqid('NEW', TRUE);
// $fieldArray is set as current record.
// The point is that when new records are created as copies with flex type fields there might be a field containing information about which DataStructure to use and without that information the flexforms cannot be correctly processed.... This should be OK since the $checkValueRecord is used by the flexform evaluation only anyways...
$this->checkValue_currentRecord = $fieldArray;
......
......@@ -316,7 +316,7 @@ class DatabaseConnection {
* @see exec_SELECTquery()
*/
public function exec_SELECT_mm_query($select, $local_table, $mm_table, $foreign_table, $whereClause = '', $groupBy = '', $orderBy = '', $limit = '') {
$foreign_table_as = $foreign_table == $local_table ? $foreign_table . uniqid('_join') : '';
$foreign_table_as = $foreign_table == $local_table ? $foreign_table . str_replace('.', '', uniqid('_join', TRUE)) : '';
$mmWhere = $local_table ? $local_table . '.uid=' . $mm_table . '.uid_local' : '';
$mmWhere .= ($local_table and $foreign_table) ? ' AND ' : '';
$tables = ($local_table ? $local_table . ',' : '') . $mm_table;
......
......@@ -1966,7 +1966,7 @@ class GraphicalFunctions {
*/
public function randomName() {
$this->createTempSubDir('temp/');
return $this->tempPath . 'temp/' . md5(uniqid(''));
return $this->tempPath . 'temp/' . md5(uniqid('', TRUE));
}
/**
......
......@@ -209,7 +209,7 @@ class PackageManager extends \TYPO3\Flow\Package\PackageManager implements \TYPO
$cacheEntryIdentifier = $this->getCacheEntryIdentifier();
if ($cacheEntryIdentifier !== NULL && !$this->coreCache->has($cacheEntryIdentifier)) {
// Package objects get their own cache entry, so PHP does not have to parse the serialized string
$packageObjectsCacheEntryIdentifier = uniqid('PackageObjects_');
$packageObjectsCacheEntryIdentifier = str_replace('.', '', uniqid('PackageObjects_', TRUE));
// Build cache file
$packageCache = array(
'packageStatesConfiguration' => $this->packageStatesConfiguration,
......
Supports Markdown
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