diff --git a/Classes/Configuration/ConfigurationReader.php b/Classes/Configuration/ConfigurationReader.php index 00ebe783..d349b665 100644 --- a/Classes/Configuration/ConfigurationReader.php +++ b/Classes/Configuration/ConfigurationReader.php @@ -87,6 +87,7 @@ class ConfigurationReader { 'fileName/defaultToHTMLsuffixOnPrev' => FALSE, 'init/appendMissingSlash' => 'ifNotFile,redirect[301]', 'init/emptySegmentValue' => '', + 'init/calculateChashIfMissing' => false, 'pagePath/spaceCharacter' => '-', // undocumented & deprecated! ); diff --git a/Classes/Decoder/UrlDecoder.php b/Classes/Decoder/UrlDecoder.php index 9f205597..425af943 100644 --- a/Classes/Decoder/UrlDecoder.php +++ b/Classes/Decoder/UrlDecoder.php @@ -179,6 +179,33 @@ public function storeCacheRecord() { } } + /** + * Calculates and adds cHash to the entry. This function is only called + * if we had to decode the entry, which was not in the cache. Even if we + * had cHash in the URL, we force to re-calculate it because we could have + * decoded parameters differently than the original URL had (for example, + * skipped some noMatch parameters). + * + * cHash recalculation can have bad consequences for the page cache. For + * details see the following links: + * - https://typo3.org/teams/security/security-bulletins/typo3-extensions/typo3-ext-sa-2016-021/ + * - https://github.com/dmitryd/typo3-realurl/issues/244#issuecomment-245844501 + * + * @param UrlCacheEntry $cacheEntry + * @return void + */ + protected function calculateChash(UrlCacheEntry $cacheEntry) { + $requestVariables = $cacheEntry->getRequestVariables(); + $cacheHashCalculator = GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\Page\\CacheHashCalculator'); + /* @var \TYPO3\CMS\Frontend\Page\CacheHashCalculator $cacheHashCalculator */ + $cHashParameters = $cacheHashCalculator->getRelevantParameters(GeneralUtility::implodeArrayForUrl('', $requestVariables)); + + if (count($cHashParameters) > 0) { + $requestVariables['cHash'] = $cacheHashCalculator->calculateCacheHash($cHashParameters); + $cacheEntry->setRequestVariables($requestVariables); + } + } + /** * Calls user-defined hooks. * @@ -1288,12 +1315,19 @@ protected function putToUrlCache(UrlCacheEntry $cacheEntry) { protected function runDecoding() { $urlPath = $this->getUrlPath(); + $calculateChash = false; $cacheEntry = $this->getFromUrlCache($this->speakingUri); if (!$cacheEntry) { $this->originalPath = $urlPath; $cacheEntry = $this->doDecoding($urlPath); + $calculateChash = (bool)$this->configuration->get('init/calculateChashIfMissing'); } $this->checkExpiration($cacheEntry); + + if ($calculateChash) { + $this->calculateChash($cacheEntry); + } + $this->setRequestVariables($cacheEntry); $this->createdCacheEntry = $cacheEntry;