diff --git a/typo3/sysext/frontend/Classes/Middleware/PageArgumentValidator.php b/typo3/sysext/frontend/Classes/Middleware/PageArgumentValidator.php index 65d64a58bdc894a6f65a40cf0027b436be9d411e..6d95e54f5c2183f62222e0ec27a28da2b7ffed30 100644 --- a/typo3/sysext/frontend/Classes/Middleware/PageArgumentValidator.php +++ b/typo3/sysext/frontend/Classes/Middleware/PageArgumentValidator.php @@ -20,6 +20,9 @@ use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\RequestHandlerInterface; +use Psr\Log\LoggerAwareInterface; +use Psr\Log\LoggerAwareTrait; +use TYPO3\CMS\Core\Http\RedirectResponse; use TYPO3\CMS\Core\Routing\PageArguments; use TYPO3\CMS\Core\TimeTracker\TimeTracker; use TYPO3\CMS\Core\Utility\GeneralUtility; @@ -32,8 +35,9 @@ use TYPO3\CMS\Frontend\Page\PageAccessFailureReasons; /** * This middleware validates given request parameters against the common "cHash" functionality. */ -class PageArgumentValidator implements MiddlewareInterface +class PageArgumentValidator implements MiddlewareInterface, LoggerAwareInterface { + use LoggerAwareTrait; /** * The cHash Service class used for cHash related functionality @@ -77,6 +81,14 @@ class PageArgumentValidator implements MiddlewareInterface $queryParams = $request->getQueryParams(); } if (!empty($queryParams) && !$this->evaluateCacheHashParameter($queryParams, $pageNotFoundOnValidationError)) { + // cHash was given, but nothing to be calculated, so let's do a redirect to the current page + // but without the cHash + if ($this->controller->cHash && empty($this->controller->cHash_array)) { + $uri = $request->getUri(); + unset($queryParams['cHash']); + $uri = $uri->withQuery(HttpUtility::buildQueryString($queryParams)); + return new RedirectResponse($uri, 308); + } return GeneralUtility::makeInstance(ErrorController::class)->pageNotFoundAction( $request, 'Request parameters could not be validated (&cHash comparison failed)', @@ -104,14 +116,12 @@ class PageArgumentValidator implements MiddlewareInterface $queryParams['id'] = $this->controller->id; $relevantParameters = $this->cacheHashCalculator->getRelevantParameters(HttpUtility::buildQueryString($queryParams)); $this->controller->cHash_array = $relevantParameters; - $calculatedCacheHash = $this->cacheHashCalculator->calculateCacheHash($relevantParameters); // cHash was given, but nothing to be calculated, so cHash is unset and all is good. if (empty($relevantParameters)) { - $this->getTimeTracker()->setTSlogMessage('The incoming cHash "' . $this->controller->cHash . '" is given but not needed. cHash is unset', 2); - // We do not need to update the query params as everything is checked via $TSFE->cHash, see $TSFE->reqCHash() - $this->controller->cHash = ''; - return true; + $this->logger->notice('The incoming cHash "' . $this->controller->cHash . '" is given but not needed. cHash is unset'); + return false; } + $calculatedCacheHash = $this->cacheHashCalculator->calculateCacheHash($relevantParameters); if (!hash_equals($calculatedCacheHash, $this->controller->cHash)) { // Early return to trigger the error controller if ($pageNotFoundOnCacheHashError) { diff --git a/typo3/sysext/frontend/Tests/Unit/Middleware/PageArgumentValidatorTest.php b/typo3/sysext/frontend/Tests/Unit/Middleware/PageArgumentValidatorTest.php index af4fa0ff46d64ceda3c6515ee9232e90889f02be..b8ac1bea1ae1f9f0b0339238f2dc83d43afd06ab 100644 --- a/typo3/sysext/frontend/Tests/Unit/Middleware/PageArgumentValidatorTest.php +++ b/typo3/sysext/frontend/Tests/Unit/Middleware/PageArgumentValidatorTest.php @@ -19,6 +19,7 @@ namespace TYPO3\CMS\Frontend\Tests\Unit\Middleware; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\RequestHandlerInterface; +use Psr\Log\NullLogger; use TYPO3\CMS\Core\Http\Response; use TYPO3\CMS\Core\Http\ServerRequest; use TYPO3\CMS\Core\Routing\PageArguments; @@ -71,9 +72,10 @@ class PageArgumentValidatorTest extends UnitTestCase /** * @test */ - public function givenCacheHashWithoutRequiredParametersIgnoresCacheHashAndUnsetsCacheHash(): void + public function givenCacheHashWithoutRequiredParametersTriggersRedirect(): void { - $incomingUrl = 'https://example.com/lotus-flower/en/mr-magpie/bloom/'; + $incomingUrl = 'https://example.com/lotus-flower/en/mr-magpie/bloom/?cHash=XYZ'; + $expectedResult = 'https://example.com/lotus-flower/en/mr-magpie/bloom/'; $this->controller->id = 13; $this->controller->cHash = 'XYZ'; @@ -83,9 +85,11 @@ class PageArgumentValidatorTest extends UnitTestCase $request = $request->withAttribute('routing', $pageArguments); $subject = new PageArgumentValidator($this->controller); + $subject->setLogger(new NullLogger()); + $response = $subject->process($request, $this->responseOutputHandler); - static::assertEquals(200, $response->getStatusCode()); - static::assertEquals('', $this->controller->cHash); + static::assertEquals(308, $response->getStatusCode()); + static::assertEquals($expectedResult, $response->getHeader('Location')[0]); } /** @@ -93,7 +97,7 @@ class PageArgumentValidatorTest extends UnitTestCase */ public function givenCacheHashNotMatchingCalculatedCacheHashTriggers404(): void { - $incomingUrl = 'https://example.com/lotus-flower/en/mr-magpie/bloom/'; + $incomingUrl = 'https://example.com/lotus-flower/en/mr-magpie/bloom/?cHash=YAZ'; $this->controller->id = 13; $this->controller->cHash = 'XYZ';