Skip to content

Commit

Permalink
mautic#8345 URL validation improvement
Browse files Browse the repository at this point in the history
  • Loading branch information
kuzmany committed Sep 11, 2020
1 parent 2423494 commit a542076
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 3 deletions.
17 changes: 17 additions & 0 deletions app/bundles/CoreBundle/Helper/UrlHelper.php
Expand Up @@ -323,4 +323,21 @@ private static function removeTrailingNonAlphaNumeric($string)

return $string;
}

/**
* This method return true with special characters in URL, for example https://domain.tld/é.pdf
* filter_var($url, FILTER_VALIDATE_URL) allow only alphanumerics [0-9a-zA-Z], the special characters "$-_.+!*'()," [not including the quotes - ed].
*
* @param string $url
*
* @return bool
*/
public static function isValidUrl($url)
{
$path = parse_url($url, PHP_URL_PATH);
$encodedPath = array_map('urlencode', explode('/', $path));
$url = str_replace($path, implode('/', $encodedPath), $url);

return (bool) filter_var($url, FILTER_VALIDATE_URL);
}
}
8 changes: 8 additions & 0 deletions app/bundles/CoreBundle/Tests/Unit/Helper/UrlHelperTest.php
Expand Up @@ -194,4 +194,12 @@ public function testSanitizeAbsoluteUrlSanitizeQueryRedirect()
UrlHelper::sanitizeAbsoluteUrl('http://username:password@hostname:9090/path?ar g1=value?arg2=some+email@address.com#anchor')
);
}

public function testUrlValid()
{
$this->assertTrue(UrlHelper::isValidUrl('https://domain.tld/e'));
$this->assertTrue(UrlHelper::isValidUrl('https://domain.tld/é'));
$this->assertFalse(UrlHelper::isValidUrl('notvalidurl'));
$this->assertFalse(UrlHelper::isValidUrl('notvalidurlé'));
}
}
6 changes: 3 additions & 3 deletions app/bundles/PageBundle/Controller/PublicController.php
Expand Up @@ -456,7 +456,7 @@ public function redirectAction($redirectId)
if (count($query)) {
$url = UrlHelper::appendQueryToUrl($url, http_build_query($query));
}

// If the IP address is not trackable, it means it came form a configured "do not track" IP or a "do not track" user agent
// This prevents simulated clicks from 3rd party services such as URL shorteners from simulating clicks
$ipAddress = $this->container->get('mautic.helper.ip_lookup')->getIpAddress();
Expand Down Expand Up @@ -498,7 +498,7 @@ public function redirectAction($redirectId)

$url = UrlHelper::sanitizeAbsoluteUrl($url);

if (false === filter_var($url, FILTER_VALIDATE_URL)) {
if (!UrlHelper::isValidUrl($url)) {
throw $this->createNotFoundException($this->translator->trans('mautic.core.url.error.404', ['%url%' => $url]));
}

Expand Down Expand Up @@ -544,7 +544,7 @@ private function replacePageTokenUrl($url)
*/
private function urlIsToken($url)
{
return substr($url, 0, 1) === '{';
return '{' === substr($url, 0, 1);
}

/**
Expand Down

0 comments on commit a542076

Please sign in to comment.