From 8085e538dd013a09faa2198d49078804a9f1f96f Mon Sep 17 00:00:00 2001 From: Torben Hansen <derhansen@gmail.com> Date: Wed, 15 Feb 2023 09:17:44 +0100 Subject: [PATCH] [BUGFIX] Consider failed logins for felogin redirect mode 'referer' The redirect mode `referer` has been fixed with #91844. The fix is however incomplete, since it always uses the current HTTP_REFERER for redirect evaluation. This is problematic, if the login fails due to wrong credentials. In such a scenario, the user is redirected to the login page, which also overwrites the original HTTP_REFERER and results in the user being redirected to the login page after successful login. This patch ensures, that the original HTTP_REFERER is evaluated in the loginAction and passed as a variable to the login form, where it is used in the hidden field `referer`. This ensures, that the initial evaluated referer is kept in the failed login scenario. Resolves: #99920 Related: #91844 Releases: main, 11.5 Signed-off-by: Torben Hansen <derhansen@gmail.com> Change-Id: Ibe572832f443beaa9b1997f767a8777f282038c4 Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/77859 Reviewed-by: Felix Nagel Reviewed-by: Benni Mack <benni@typo3.org> Tested-by: core-ci <typo3@b13.com> Tested-by: Benni Mack <benni@typo3.org> Reviewed-by: Markus Klein <markus.klein@typo3.org> Tested-by: Markus Klein <markus.klein@typo3.org> Tested-by: Felix Nagel Reviewed-by: Thomas Hohn <tho@gyldendal.dk> --- .../Classes/Controller/LoginController.php | 30 ++++++++++++++++++- .../Classes/Redirect/RedirectModeHandler.php | 3 -- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/typo3/sysext/felogin/Classes/Controller/LoginController.php b/typo3/sysext/felogin/Classes/Controller/LoginController.php index 9e4289d3397c..80105916dfb2 100644 --- a/typo3/sysext/felogin/Classes/Controller/LoginController.php +++ b/typo3/sysext/felogin/Classes/Controller/LoginController.php @@ -31,6 +31,7 @@ use TYPO3\CMS\FrontendLogin\Event\LogoutConfirmedEvent; use TYPO3\CMS\FrontendLogin\Event\ModifyLoginFormViewEvent; use TYPO3\CMS\FrontendLogin\Redirect\RedirectHandler; use TYPO3\CMS\FrontendLogin\Service\UserService; +use TYPO3\CMS\FrontendLogin\Validation\RedirectUrlValidator; /** * Used for plugin login @@ -52,6 +53,7 @@ class LoginController extends AbstractLoginFormController public function __construct( protected RedirectHandler $redirectHandler, protected UserService $userService, + protected RedirectUrlValidator $redirectUrlValidator, protected Context $context ) { $this->userAspect = $context->getAspect('frontend.user'); @@ -107,7 +109,7 @@ class LoginController extends AbstractLoginFormController 'permaloginStatus' => $this->getPermaloginStatus(), 'redirectURL' => $this->redirectHandler->getLoginFormRedirectUrl($this->request, $this->configuration, $this->isRedirectDisabled()), 'redirectReferrer' => $this->request->hasArgument('redirectReferrer') ? (string)$this->request->getArgument('redirectReferrer') : '', - 'referer' => (string)($this->request->getParsedBody()['referer'] ?? $this->request->getQueryParams()['referer'] ?? ''), + 'referer' => $this->getRefererForLoginForm(), 'noRedirect' => $this->isRedirectDisabled(), 'requestToken' => RequestToken::create('core/user-auth/fe') ->withMergedParams(['pid' => implode(',', $this->getStorageFolders())]), @@ -168,6 +170,32 @@ class LoginController extends AbstractLoginFormController return $this->htmlResponse(); } + /** + * Determines the `referer` variable used in the login form for loginMode=referer depending on the + * following evaluation order: + * + * - HTTP POST parameter `referer` + * - HTTP GET parameter `referer` + * - HTTP_REFERER + * + * The evaluated `referer` is only returned, if it is considered as valid. + */ + protected function getRefererForLoginForm(): string + { + $referer = (string)( + $this->request->getParsedBody()['referer'] ?? + $this->request->getQueryParams()['referer'] ?? + $this->request->getServerParams()['HTTP_REFERER'] ?? + '' + ); + + if ($this->redirectUrlValidator->isValid($this->request, $referer)) { + return $referer; + } + + return ''; + } + /** * Handles the redirect when $this->redirectUrl is not empty */ diff --git a/typo3/sysext/felogin/Classes/Redirect/RedirectModeHandler.php b/typo3/sysext/felogin/Classes/Redirect/RedirectModeHandler.php index 0f0fa3f5680f..3a9e7e07b6d4 100644 --- a/typo3/sysext/felogin/Classes/Redirect/RedirectModeHandler.php +++ b/typo3/sysext/felogin/Classes/Redirect/RedirectModeHandler.php @@ -186,9 +186,6 @@ class RedirectModeHandler { $referer = ''; $requestReferer = (string)($request->getParsedBody()['referer'] ?? $request->getQueryParams()['referer'] ?? ''); - if ($requestReferer === '') { - $requestReferer = $request->getServerParams()['HTTP_REFERER'] ?? ''; - } if ($this->redirectUrlValidator->isValid($request, $requestReferer)) { $referer = $requestReferer; -- GitLab