Skip to content

Commit edb73e1

Browse files
author
Tim Ward
committed
[Security] Allow redirect after login to absolute URLs
Fixes #46533
1 parent 0af230c commit edb73e1

4 files changed

+34
-2
lines changed

Authentication/DefaultAuthenticationFailureHandler.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public function onAuthenticationFailure(Request $request, AuthenticationExceptio
7373
$options = $this->options;
7474
$failureUrl = ParameterBagUtils::getRequestParameterValue($request, $options['failure_path_parameter']);
7575

76-
if (\is_string($failureUrl) && str_starts_with($failureUrl, '/')) {
76+
if (\is_string($failureUrl) && (str_starts_with($failureUrl, '/') || str_starts_with($failureUrl, 'http'))) {
7777
$options['failure_path'] = $failureUrl;
7878
} elseif ($this->logger && $failureUrl) {
7979
$this->logger->debug(sprintf('Ignoring query parameter "%s": not a valid URL.', $options['failure_path_parameter']));

Authentication/DefaultAuthenticationSuccessHandler.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ protected function determineTargetUrl(Request $request)
107107

108108
$targetUrl = ParameterBagUtils::getRequestParameterValue($request, $this->options['target_path_parameter']);
109109

110-
if (\is_string($targetUrl) && str_starts_with($targetUrl, '/')) {
110+
if (\is_string($targetUrl) && (str_starts_with($targetUrl, '/') || str_starts_with($targetUrl, 'http'))) {
111111
return $targetUrl;
112112
}
113113

Tests/Authentication/DefaultAuthenticationFailureHandlerTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,21 @@ public function testFailurePathFromRequestWithInvalidUrl()
207207
$handler->onAuthenticationFailure($this->request, $this->exception);
208208
}
209209

210+
public function testAbsoluteUrlRedirectionFromRequest()
211+
{
212+
$options = ['failure_path_parameter' => '_my_failure_path'];
213+
214+
$this->request->expects($this->once())
215+
->method('get')->with('_my_failure_path')
216+
->willReturn('https://localhost/some-path');
217+
218+
$this->httpUtils->expects($this->once())
219+
->method('createRedirectResponse')->with($this->request, 'https://localhost/some-path');
220+
221+
$handler = new DefaultAuthenticationFailureHandler($this->httpKernel, $this->httpUtils, $options, $this->logger);
222+
$handler->onAuthenticationFailure($this->request, $this->exception);
223+
}
224+
210225
private function getRequest()
211226
{
212227
$request = $this->createMock(Request::class);

Tests/Authentication/DefaultAuthenticationSuccessHandlerTest.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,4 +135,21 @@ public function testTargetPathFromRequestWithInvalidUrl()
135135

136136
$handler->onAuthenticationSuccess($request, $token);
137137
}
138+
139+
public function testTargetPathWithAbsoluteUrlFromRequest()
140+
{
141+
$options = ['target_path_parameter' => '_my_target_path'];
142+
143+
$request = $this->createMock(Request::class);
144+
$request->expects($this->once())
145+
->method('get')->with('_my_target_path')
146+
->willReturn('https://localhost/some-path');
147+
148+
$httpUtils = $this->createMock(HttpUtils::class);
149+
$httpUtils->expects($this->once())
150+
->method('createRedirectResponse')->with($request, 'https://localhost/some-path');
151+
152+
$handler = new DefaultAuthenticationSuccessHandler($httpUtils, $options);
153+
$handler->onAuthenticationSuccess($request, $this->createMock(TokenInterface::class));
154+
}
138155
}

0 commit comments

Comments
 (0)