From f553d918cb69eb9dc525cad689ce44c08e9b5f43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20E=C3=9Fl?= <indy.essl@gmail.com> Date: Sun, 16 Feb 2020 14:38:41 +0100 Subject: [PATCH] [BUGFIX] Throw BadRequestException on failed hmac validation from forms If a HMAC of a submitted form is invalid (because it has been tampered with), TYPO3 would previously throw an exception that leads to a status code 500. This is incorrect behaviour, as the error comes from bad user input and not a server error. In case the HMAC of a submitted form is invalid, both extbase and ext:form will now throw a BadRequestException, which will then lead to a status code 400 (BAD REQUEST). Resolves: #90134 Releases: master, 9.5 Change-Id: If4dad7ba27190b5992bab68b4ce64a423c0db645 Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/63272 Tested-by: TYPO3com <noreply@typo3.com> Tested-by: Markus Klein <markus.klein@typo3.org> Tested-by: Alexander Schnitzler <git@alexanderschnitzler.de> Tested-by: Georg Ringer <georg.ringer@gmail.com> Reviewed-by: Markus Klein <markus.klein@typo3.org> Reviewed-by: Daniel Goerz <daniel.goerz@posteo.de> Reviewed-by: Alexander Schnitzler <git@alexanderschnitzler.de> Reviewed-by: Georg Ringer <georg.ringer@gmail.com> --- ...MvcPropertyMappingConfigurationService.php | 11 ++++++++++- ...ropertyMappingConfigurationServiceTest.php | 19 +++++++++++++++++++ .../Classes/Domain/Runtime/FormRuntime.php | 10 +++++++++- 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/typo3/sysext/extbase/Classes/Mvc/Controller/MvcPropertyMappingConfigurationService.php b/typo3/sysext/extbase/Classes/Mvc/Controller/MvcPropertyMappingConfigurationService.php index 355d72fafb6a..2dff40ad45ca 100644 --- a/typo3/sysext/extbase/Classes/Mvc/Controller/MvcPropertyMappingConfigurationService.php +++ b/typo3/sysext/extbase/Classes/Mvc/Controller/MvcPropertyMappingConfigurationService.php @@ -14,6 +14,10 @@ namespace TYPO3\CMS\Extbase\Mvc\Controller; * The TYPO3 project - inspiring people to share! */ +use TYPO3\CMS\Core\Error\Http\BadRequestException; +use TYPO3\CMS\Extbase\Security\Exception\InvalidArgumentForHashGenerationException; +use TYPO3\CMS\Extbase\Security\Exception\InvalidHashException; + /** * This is a Service which can generate a request hash and check whether the currently given arguments * fit to the request hash. @@ -117,6 +121,7 @@ class MvcPropertyMappingConfigurationService implements \TYPO3\CMS\Core\Singleto * * @param \TYPO3\CMS\Extbase\Mvc\Request $request * @param \TYPO3\CMS\Extbase\Mvc\Controller\Arguments $controllerArguments + * @throws BadRequestException */ public function initializePropertyMappingConfigurationFromRequest(\TYPO3\CMS\Extbase\Mvc\Request $request, \TYPO3\CMS\Extbase\Mvc\Controller\Arguments $controllerArguments) { @@ -125,7 +130,11 @@ class MvcPropertyMappingConfigurationService implements \TYPO3\CMS\Core\Singleto return; } - $serializedTrustedProperties = $this->hashService->validateAndStripHmac($trustedPropertiesToken); + try { + $serializedTrustedProperties = $this->hashService->validateAndStripHmac($trustedPropertiesToken); + } catch (InvalidHashException | InvalidArgumentForHashGenerationException $e) { + throw new BadRequestException('The HMAC of the form could not be validated.', 1581862822); + } $trustedProperties = json_decode($serializedTrustedProperties, true); foreach ($trustedProperties as $propertyName => $propertyConfiguration) { if (!$controllerArguments->hasArgument($propertyName)) { diff --git a/typo3/sysext/extbase/Tests/Unit/Mvc/Controller/MvcPropertyMappingConfigurationServiceTest.php b/typo3/sysext/extbase/Tests/Unit/Mvc/Controller/MvcPropertyMappingConfigurationServiceTest.php index 775577a43fe9..bad2986ed18e 100644 --- a/typo3/sysext/extbase/Tests/Unit/Mvc/Controller/MvcPropertyMappingConfigurationServiceTest.php +++ b/typo3/sysext/extbase/Tests/Unit/Mvc/Controller/MvcPropertyMappingConfigurationServiceTest.php @@ -14,6 +14,7 @@ namespace TYPO3\CMS\Extbase\Tests\Unit\Mvc\Controller; * The TYPO3 project - inspiring people to share! */ +use TYPO3\CMS\Core\Error\Http\BadRequestException; use TYPO3\CMS\Extbase\Mvc\Controller\MvcPropertyMappingConfigurationService; use TYPO3\CMS\Extbase\Security\Cryptography\HashService; use TYPO3\CMS\Extbase\Security\Exception\InvalidArgumentForHashGenerationException; @@ -184,6 +185,24 @@ class MvcPropertyMappingConfigurationServiceTest extends UnitTestCase $requestHashService->initializePropertyMappingConfigurationFromRequest($request, $arguments); } + /** + * @test + */ + public function initializePropertyMappingConfigurationThrowsBadRequestExceptionOnInvalidHmac() + { + $this->expectException(BadRequestException::class); + $this->expectExceptionCode(1581862822); + + $request = $this->getMockBuilder(\TYPO3\CMS\Extbase\Mvc\Request::class)->setMethods(['getInternalArgument'])->disableOriginalConstructor()->getMock(); + $request->expects(self::any())->method('getInternalArgument')->with('__trustedProperties')->willReturn('string with less than 40 characters'); + $arguments = new \TYPO3\CMS\Extbase\Mvc\Controller\Arguments(); + + $hashService = new \TYPO3\CMS\Extbase\Security\Cryptography\HashService(); + $requestHashService = new MvcPropertyMappingConfigurationService; + $requestHashService->injectHashService($hashService); + $requestHashService->initializePropertyMappingConfigurationFromRequest($request, $arguments); + } + /** * @test */ diff --git a/typo3/sysext/form/Classes/Domain/Runtime/FormRuntime.php b/typo3/sysext/form/Classes/Domain/Runtime/FormRuntime.php index 252f73d0cd87..3e76003e70ca 100644 --- a/typo3/sysext/form/Classes/Domain/Runtime/FormRuntime.php +++ b/typo3/sysext/form/Classes/Domain/Runtime/FormRuntime.php @@ -19,6 +19,7 @@ namespace TYPO3\CMS\Form\Domain\Runtime; use Psr\Http\Message\ServerRequestInterface; use TYPO3\CMS\Core\Context\Context; +use TYPO3\CMS\Core\Error\Http\BadRequestException; use TYPO3\CMS\Core\ExpressionLanguage\Resolver; use TYPO3\CMS\Core\Http\ServerRequest; use TYPO3\CMS\Core\Site\Entity\Site; @@ -33,6 +34,8 @@ use TYPO3\CMS\Extbase\Mvc\Web\Request; use TYPO3\CMS\Extbase\Mvc\Web\Response; use TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder; use TYPO3\CMS\Extbase\Property\Exception as PropertyException; +use TYPO3\CMS\Extbase\Security\Exception\InvalidArgumentForHashGenerationException; +use TYPO3\CMS\Extbase\Security\Exception\InvalidHashException; use TYPO3\CMS\Form\Domain\Exception\RenderingException; use TYPO3\CMS\Form\Domain\Finishers\FinisherContext; use TYPO3\CMS\Form\Domain\Finishers\FinisherInterface; @@ -210,6 +213,7 @@ class FormRuntime implements RootRenderableInterface, \ArrayAccess /** * Initializes the current state of the form, based on the request + * @throws BadRequestException */ protected function initializeFormStateFromRequest() { @@ -217,7 +221,11 @@ class FormRuntime implements RootRenderableInterface, \ArrayAccess if ($serializedFormStateWithHmac === null) { $this->formState = GeneralUtility::makeInstance(FormState::class); } else { - $serializedFormState = $this->hashService->validateAndStripHmac($serializedFormStateWithHmac); + try { + $serializedFormState = $this->hashService->validateAndStripHmac($serializedFormStateWithHmac); + } catch (InvalidHashException | InvalidArgumentForHashGenerationException $e) { + throw new BadRequestException('The HMAC of the form could not be validated.', 1581862823); + } $this->formState = unserialize(base64_decode($serializedFormState)); } } -- GitLab