From 9053014a7e2eba28d000881e0bb3cc1d6e6b2eea Mon Sep 17 00:00:00 2001 From: Damian Mooyman Date: Tue, 10 Apr 2018 16:45:14 +1200 Subject: [PATCH] [ss-2018-008] Validate against malformed urls --- src/Control/Director.php | 25 +++++++++++++++++++------ tests/php/Control/DirectorTest.php | 4 ++++ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/Control/Director.php b/src/Control/Director.php index 316148578..88908ef6e 100644 --- a/src/Control/Director.php +++ b/src/Control/Director.php @@ -728,13 +728,26 @@ class Director implements TemplateGlobalProvider */ public static function is_site_url($url) { - $urlHost = parse_url($url, PHP_URL_HOST); - $actualHost = parse_url(self::protocolAndHost(), PHP_URL_HOST); - if ($urlHost && $actualHost && $urlHost == $actualHost) { - return true; - } else { - return self::is_relative_url($url); + $parsedURL = parse_url($url); + + // Validate user (disallow slashes) + if (!empty($parsedURL['user']) && strstr($parsedURL['user'], '\\')) { + return false; } + if (!empty($parsedURL['pass']) && strstr($parsedURL['pass'], '\\')) { + return false; + } + + // Validate host[:port] + $actualHost = parse_url(self::protocolAndHost(), PHP_URL_HOST); + if (!empty($parsedURL['host']) + && $actualHost + && $parsedURL['host'] === $actualHost + ) { + return true; + } + + return self::is_relative_url($url); } /** diff --git a/tests/php/Control/DirectorTest.php b/tests/php/Control/DirectorTest.php index eae00b2b8..9a1de2ec4 100644 --- a/tests/php/Control/DirectorTest.php +++ b/tests/php/Control/DirectorTest.php @@ -380,6 +380,10 @@ class DirectorTest extends SapphireTest $this->assertFalse(Director::is_site_url("http://test.com?url=" . Director::absoluteBaseURL())); $this->assertFalse(Director::is_site_url("http://test.com?url=" . urlencode(Director::absoluteBaseURL()))); $this->assertFalse(Director::is_site_url("//test.com?url=" . Director::absoluteBaseURL())); + $this->assertFalse(Director::is_site_url('http://google.com\@test.com')); + $this->assertFalse(Director::is_site_url('http://google.com/@test.com')); + $this->assertFalse(Director::is_site_url('http://google.com:pass\@test.com')); + $this->assertFalse(Director::is_site_url('http://google.com:pass/@test.com')); } /**