Skip to content

Commit

Permalink
bug #50552 [Security] Allow custom scheme to be used as redirection U…
Browse files Browse the repository at this point in the history
…RIs (Spomky)

This PR was merged into the 5.4 branch.

Discussion
----------

[Security] Allow custom scheme to be used as redirection URIs

| Q             | A
| ------------- | ---
| Branch?       | 5.4
| Bug fix?      | yes
| New feature?  | no <!-- please update src/**/CHANGELOG.md files -->
| Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tickets       | Fix #50500
| License       | MIT
| Doc PR        | not needed

ping `@sdespont` and `@MatTheCat`

This PR aims at fixing the redirection issue where only URLs starting with `http` are allowed.
With the modified behavior, it is now allowed to use any URL scheme. It will be possible to redirect to `android-app://com.google.android.gm/`.

~In addition, it prevents the redirection to the following URLs:~

* ~With path traversal e.g. `https://example.com/foo/../../.htpasswd`~
* ~With protocol-relative e.g. `//malicious.app/foo/bar`~

Commits
-------

3a6969f363 [Security] Allow custom scheme to be used as redirection URIs
  • Loading branch information
nicolas-grekas committed Jul 13, 2023
2 parents 84aa665 + 317963e commit 9291eec
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 1 deletion.
4 changes: 3 additions & 1 deletion HttpUtils.php
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,9 @@ public function checkRequestPath(Request $request, string $path)
*/
public function generateUri(Request $request, string $path)
{
if (str_starts_with($path, 'http') || !$path) {
$url = parse_url($path);

if ('' === $path || isset($url['scheme'], $url['host'])) {
return $path;
}

Expand Down
49 changes: 49 additions & 0 deletions Tests/HttpUtilsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,54 @@ public function testCreateRedirectResponseWithRequestsDomain()
$this->assertTrue($response->isRedirect('http://localhost/blog'));
}

/**
* @dataProvider validRequestDomainUrls
*/
public function testCreateRedirectResponse(?string $domainRegexp, string $path, string $expectedRedirectUri)
{
$utils = new HttpUtils($this->getUrlGenerator(), null, $domainRegexp);
$response = $utils->createRedirectResponse($this->getRequest(), $path);

$this->assertTrue($response->isRedirect($expectedRedirectUri));
$this->assertEquals(302, $response->getStatusCode());
}

public static function validRequestDomainUrls()
{
return [
'/foobar' => [
null,
'/foobar',
'http://localhost/foobar',
],
'http://symfony.com/ without domain regex' => [
null,
'http://symfony.com/',
'http://symfony.com/',
],
'http://localhost/blog with #^https?://symfony\.com$#i' => [
'#^https?://symfony\.com$#i',
'http://symfony.com/blog',
'http://symfony.com/blog',
],
'http://localhost/blog with #^https?://%s$#i' => [
'#^https?://%s$#i',
'http://localhost/blog',
'http://localhost/blog',
],
'custom scheme' => [
null,
'android-app://com.google.android.gm/',
'android-app://com.google.android.gm/',
],
'custom scheme with all URL components' => [
null,
'android-app://foo:bar@www.example.com:8080/software/index.html?lite=true#section1',
'android-app://foo:bar@www.example.com:8080/software/index.html?lite=true#section1',
],
];
}

/**
* @dataProvider badRequestDomainUrls
*/
Expand All @@ -77,6 +125,7 @@ public static function badRequestDomainUrls()
['http:/\\pirate.net/foo'],
['http:\\/pirate.net/foo'],
['http://////pirate.net/foo'],
['http:///foo'],
];
}

Expand Down

0 comments on commit 9291eec

Please sign in to comment.