Merge pull request #5 from silverstripe-security/patch/3.4/SS-2017-003

[SS-2017-003] Only allow HTTP(S) links for external redirector pages
This commit is contained in:
Daniel Hensby 2017-05-28 21:36:33 +00:00
commit 02b5e6ea92
No known key found for this signature in database
GPG Key ID: B00D1E9767F0B06E
2 changed files with 28 additions and 7 deletions

View File

@ -106,13 +106,23 @@ class RedirectorPage extends Page {
public function onBeforeWrite() { public function onBeforeWrite() {
parent::onBeforeWrite(); parent::onBeforeWrite();
// Prefix the URL with "http://" if no prefix is found if ($this->ExternalURL && substr($this->ExternalURL, 0, 2) !== '//') {
if( $urlParts = parse_url($this->ExternalURL);
$this->ExternalURL if ($urlParts) {
&& !parse_url($this->ExternalURL, PHP_URL_SCHEME) if (empty($urlParts['scheme'])) {
&& !preg_match('#^//#', $this->ExternalURL) // no scheme, assume http
) {
$this->ExternalURL = 'http://' . $this->ExternalURL; $this->ExternalURL = 'http://' . $this->ExternalURL;
} elseif (!in_array($urlParts['scheme'], array(
'http',
'https',
))) {
// we only allow http(s) urls
$this->ExternalURL = '';
}
} else {
// malformed URL to reject
$this->ExternalURL = '';
}
} }
} }

View File

@ -80,6 +80,17 @@ class RedirectorPageTest extends FunctionalTest {
RedirectorPage_Controller::remove_extension('RedirectorPageTest_RedirectExtension'); RedirectorPage_Controller::remove_extension('RedirectorPageTest_RedirectExtension');
} }
public function testNoJSLinksAllowed()
{
$page = new RedirectorPage();
$js = 'javascript:alert("hello world")';
$page->ExternalURL = $js;
$this->assertEquals($js, $page->ExternalURL);
$page->write();
$this->assertEmpty($page->ExternalURL);
}
} }
class RedirectorPageTest_RedirectExtension extends Extension implements TestOnly { class RedirectorPageTest_RedirectExtension extends Extension implements TestOnly {