From 2b4ceae620261a5433aa12acf5e2b385aef40ab8 Mon Sep 17 00:00:00 2001 From: Johannes Ernst Date: Wed, 6 Jul 2016 23:38:30 +0000 Subject: [PATCH] Trusted domain wildcard checking made shorter, supporting multiple * Added test cases --- lib/private/Security/TrustedDomainHelper.php | 40 ++++--------------- .../lib/Security/TrustedDomainHelperTest.php | 27 ++++++++++++- 2 files changed, 34 insertions(+), 33 deletions(-) diff --git a/lib/private/Security/TrustedDomainHelper.php b/lib/private/Security/TrustedDomainHelper.php index be4014327b3..44e133746fd 100644 --- a/lib/private/Security/TrustedDomainHelper.php +++ b/lib/private/Security/TrustedDomainHelper.php @@ -70,7 +70,7 @@ class TrustedDomainHelper { // Read trusted domains from config $trustedList = $this->config->getSystemValue('trusted_domains', []); - if(!is_array($trustedList)) { + if (!is_array($trustedList)) { return false; } @@ -79,39 +79,15 @@ class TrustedDomainHelper { return true; } - // Compare with port appended - if(in_array($domainWithPort, $trustedList, true)) { - return true; - } - - if(in_array($domain, $trustedList, true)) { - return true; - } - - // If a value contains a *, apply glob-style matching. Any second * is ignored. - foreach ($trustedList as $trusted) { - if($trusted === '*') { + // match, allowing for * wildcards + foreach ($trustedList as $trusted) { + if (gettype($trusted) !== 'string') { + break; + } + $regex = '/^' . join('.*', array_map(function($v) { return preg_quote($v, '/'); }, explode('*', $trusted))) . '$/'; + if (preg_match($regex, $domain) || preg_match($regex, $domainWithPort)) { return true; } - $star = strpos($trusted, '*'); - if($star === false) { - break; - } - if($star === 0) { - if(strrpos($domain, substr($trusted, 1)) !== false) { - return true; - } - } elseif($star === strlen($trusted)-1) { - if(strpos($domain, substr($trusted, 0, strlen($trusted)-1 )) !== false) { - return true; - } - } else { - if(strpos($domain, substr($trusted, 0, $star)) !== false - && strrpos($domain, substr($trusted, $star+1 ), -strlen($trusted-$star-1)) !== false ) - { - return true; - } - } } return false; } diff --git a/tests/lib/Security/TrustedDomainHelperTest.php b/tests/lib/Security/TrustedDomainHelperTest.php index dfd51167cca..6c254dcaa79 100644 --- a/tests/lib/Security/TrustedDomainHelperTest.php +++ b/tests/lib/Security/TrustedDomainHelperTest.php @@ -49,6 +49,11 @@ class TrustedDomainHelperTest extends \Test\TestCase { 'host.two.test', '[1fff:0:a88:85a3::ac1f]', 'host.three.test:443', + '*.leading.host', + 'trailing.host*', + 'cen*ter', + '*.leadingwith.port:123', + 'trailingwith.port*:456', ]; return [ // empty defaults to false with 8.1 @@ -76,7 +81,27 @@ class TrustedDomainHelperTest extends \Test\TestCase { [$trustedHostTestList, 'localhost: evil.host', false], // do not trust casting [[1], '1', false], + // leading * + [$trustedHostTestList, 'abc.leading.host', true], + [$trustedHostTestList, 'abc.def.leading.host', true], + [$trustedHostTestList, 'abc.def.leading.host.another', false], + [$trustedHostTestList, 'abc.def.leading.host:123', true], + [$trustedHostTestList, 'leading.host', false], + // trailing * + [$trustedHostTestList, 'trailing.host', true], + [$trustedHostTestList, 'trailing.host.abc', true], + [$trustedHostTestList, 'trailing.host.abc.def', true], + [$trustedHostTestList, 'trailing.host.abc:123', true], + [$trustedHostTestList, 'another.trailing.host', false], + // center * + [$trustedHostTestList, 'center', true], + [$trustedHostTestList, 'cenxxxter', true], + [$trustedHostTestList, 'cen.x.y.ter', true], + // with port + [$trustedHostTestList, 'abc.leadingwith.port:123', true], + [$trustedHostTestList, 'abc.leadingwith.port:1234', false], + [$trustedHostTestList, 'trailingwith.port.abc:456', true], + [$trustedHostTestList, 'trailingwith.port.abc:123', false], ]; } - }