diff options
author | Christoph Wurst <christoph@winzerhof-wurst.at> | 2022-10-27 14:33:31 +0200 |
---|---|---|
committer | Christoph Wurst <christoph@winzerhof-wurst.at> | 2022-10-31 16:13:28 +0100 |
commit | 8aea25b5b92dac105f7e862470ee0dcf0e876615 (patch) | |
tree | 3095f0a58eb70e1c21117ce9c3450a1e60e323ba /tests/lib/Security | |
parent | aa81b87f26552bc3d49de6cf0babfe6a79c21af5 (diff) | |
download | nextcloud-server-8aea25b5b92dac105f7e862470ee0dcf0e876615.tar.gz nextcloud-server-8aea25b5b92dac105f7e862470ee0dcf0e876615.zip |
Add remote host validation API
Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
Diffstat (limited to 'tests/lib/Security')
-rw-r--r-- | tests/lib/Security/RemoteHostValidatorIntegrationTest.php | 144 | ||||
-rw-r--r-- | tests/lib/Security/RemoteHostValidatorTest.php | 111 |
2 files changed, 255 insertions, 0 deletions
diff --git a/tests/lib/Security/RemoteHostValidatorIntegrationTest.php b/tests/lib/Security/RemoteHostValidatorIntegrationTest.php new file mode 100644 index 00000000000..73cbbd7b0e8 --- /dev/null +++ b/tests/lib/Security/RemoteHostValidatorIntegrationTest.php @@ -0,0 +1,144 @@ +<?php + +declare(strict_types=1); + +/* + * @copyright 2022 Christoph Wurst <christoph@winzerhof-wurst.at> + * + * @author 2022 Christoph Wurst <christoph@winzerhof-wurst.at> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +namespace lib\Security; + +use OC\Net\HostnameClassifier; +use OC\Net\IpAddressClassifier; +use OC\Security\RemoteHostValidator; +use OCP\IConfig; +use OCP\Server; +use PHPUnit\Framework\MockObject\MockObject; +use Psr\Log\NullLogger; +use Test\TestCase; + +class RemoteHostValidatorIntegrationTest extends TestCase { + + /** @var IConfig|IConfig&MockObject|MockObject */ + private IConfig $config; + private RemoteHostValidator $validator; + + protected function setUp(): void { + parent::setUp(); + + // Mock config to avoid any side effects + $this->config = $this->createMock(IConfig::class); + + $this->validator = new RemoteHostValidator( + $this->config, + Server::get(HostnameClassifier::class), + Server::get(IpAddressClassifier::class), + new NullLogger(), + ); + } + + public function localHostsData(): array { + return [ + ['[::1]'], + ['[::]'], + ['192.168.0.1'], + ['172.16.42.1'], + ['[fdf8:f53b:82e4::53]'], + ['[fe80::200:5aee:feaa:20a2]'], + ['[0:0:0:0:0:ffff:10.0.0.1]'], + ['[0:0:0:0:0:ffff:127.0.0.0]'], + ['10.0.0.1'], + ['!@#$'], // test invalid url + ['100.100.100.200'], + ['192.0.0.1'], + ['0177.0.0.9'], + ['⑯⑨。②⑤④。⑯⑨。②⑤④'], + ['127。②⑤④。⑯⑨.②⑤④'], + ['127.0.00000000000000000000000000000000001'], + ['127.1'], + ['127.000.001'], + ['0177.0.0.01'], + ['0x7f.0x0.0x0.0x1'], + ['0x7f000001'], + ['2130706433'], + ['00000000000000000000000000000000000000000000000000177.1'], + ['0x7f.1'], + ['127.0x1'], + ['[0000:0000:0000:0000:0000:0000:0000:0001]'], + ['[0:0:0:0:0:0:0:1]'], + ['[0:0:0:0::0:0:1]'], + ['%31%32%37%2E%30%2E%30%2E%31'], + ['%31%32%37%2E%30%2E%30.%31'], + ['[%3A%3A%31]'], + ]; + } + + /** + * @dataProvider localHostsData + */ + public function testLocalHostsWhenNotAllowed(string $host): void { + $this->config + ->method('getSystemValueBool') + ->with('allow_local_remote_servers', false) + ->willReturn(false); + + $isValid = $this->validator->isValid($host); + + self::assertFalse($isValid); + } + + /** + * @dataProvider localHostsData + */ + public function testLocalHostsWhenAllowed(string $host): void { + $this->config + ->method('getSystemValueBool') + ->with('allow_local_remote_servers', false) + ->willReturn(true); + + $isValid = $this->validator->isValid($host); + + self::assertTrue($isValid); + } + + public function externalAddressesData():array { + return [ + ['8.8.8.8'], + ['8.8.4.4'], + ['8.8.8.8'], + ['8.8.4.4'], + ['[2001:4860:4860::8888]'], + ]; + } + + /** + * @dataProvider externalAddressesData + */ + public function testExternalHost(string $host): void { + $this->config + ->method('getSystemValueBool') + ->with('allow_local_remote_servers', false) + ->willReturn(false); + + $isValid = $this->validator->isValid($host); + + self::assertTrue($isValid); + } +} diff --git a/tests/lib/Security/RemoteHostValidatorTest.php b/tests/lib/Security/RemoteHostValidatorTest.php new file mode 100644 index 00000000000..acaa7a4be30 --- /dev/null +++ b/tests/lib/Security/RemoteHostValidatorTest.php @@ -0,0 +1,111 @@ +<?php + +declare(strict_types=1); + +/* + * @copyright 2022 Christoph Wurst <christoph@winzerhof-wurst.at> + * + * @author 2022 Christoph Wurst <christoph@winzerhof-wurst.at> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +namespace lib\Security; + +use OC\Net\HostnameClassifier; +use OC\Net\IpAddressClassifier; +use OC\Security\RemoteHostValidator; +use OCP\IConfig; +use PHPUnit\Framework\MockObject\MockObject; +use Psr\Log\LoggerInterface; +use Test\TestCase; + +class RemoteHostValidatorTest extends TestCase { + + /** @var IConfig|IConfig&MockObject|MockObject */ + private IConfig $config; + /** @var HostnameClassifier|HostnameClassifier&MockObject|MockObject */ + private HostnameClassifier $hostnameClassifier; + /** @var IpAddressClassifier|IpAddressClassifier&MockObject|MockObject */ + private IpAddressClassifier $ipAddressClassifier; + /** @var MockObject|LoggerInterface|LoggerInterface&MockObject */ + private LoggerInterface $logger; + private RemoteHostValidator $validator; + + protected function setUp(): void { + parent::setUp(); + + $this->config = $this->createMock(IConfig::class); + $this->hostnameClassifier = $this->createMock(HostnameClassifier::class); + $this->ipAddressClassifier = $this->createMock(IpAddressClassifier::class); + $this->logger = $this->createMock(LoggerInterface::class); + + $this->validator = new RemoteHostValidator( + $this->config, + $this->hostnameClassifier, + $this->ipAddressClassifier, + $this->logger, + ); + } + + public function testValid(): void { + $host = 'nextcloud.com'; + $this->hostnameClassifier + ->method('isLocalHostname') + ->with($host) + ->willReturn(false); + $this->ipAddressClassifier + ->method('isLocalAddress') + ->with($host) + ->willReturn(false); + + $valid = $this->validator->isValid($host); + + self::assertTrue($valid); + } + + public function testLocalHostname(): void { + $host = 'localhost'; + $this->hostnameClassifier + ->method('isLocalHostname') + ->with($host) + ->willReturn(true); + $this->ipAddressClassifier + ->method('isLocalAddress') + ->with($host) + ->willReturn(false); + + $valid = $this->validator->isValid($host); + + self::assertFalse($valid); + } + + public function testLocalAddress(): void { + $host = '10.0.0.10'; + $this->hostnameClassifier + ->method('isLocalHostname') + ->with($host) + ->willReturn(false); + $this->ipAddressClassifier + ->method('isLocalAddress') + ->with($host) + ->willReturn(true); + + $valid = $this->validator->isValid($host); + + self::assertFalse($valid); + } +} |