diff --git a/apps/dav/appinfo/v1/carddav.php b/apps/dav/appinfo/v1/carddav.php index f11281a00a82c..229a99f2e281f 100644 --- a/apps/dav/appinfo/v1/carddav.php +++ b/apps/dav/appinfo/v1/carddav.php @@ -33,6 +33,7 @@ use OCA\DAV\CardDAV\AddressBookRoot; use OCA\DAV\CardDAV\CardDavBackend; use OCA\DAV\CardDAV\Security\CardDavRateLimitingPlugin; +use OCA\DAV\CardDAV\Validation\CardDavValidatePlugin; use OCA\DAV\Connector\LegacyDAVACL; use OCA\DAV\Connector\Sabre\Auth; use OCA\DAV\Connector\Sabre\ExceptionLoggerPlugin; @@ -105,6 +106,7 @@ ))); $server->addPlugin(new ExceptionLoggerPlugin('carddav', \OC::$server->get(LoggerInterface::class))); $server->addPlugin(\OCP\Server::get(CardDavRateLimitingPlugin::class)); +$server->addPlugin(\OCP\Server::get(CardDavValidatePlugin::class)); // And off we go! $server->exec(); diff --git a/apps/dav/composer/composer/autoload_classmap.php b/apps/dav/composer/composer/autoload_classmap.php index bce266fd70a40..4a14709454bf5 100644 --- a/apps/dav/composer/composer/autoload_classmap.php +++ b/apps/dav/composer/composer/autoload_classmap.php @@ -134,6 +134,7 @@ 'OCA\\DAV\\CardDAV\\SyncService' => $baseDir . '/../lib/CardDAV/SyncService.php', 'OCA\\DAV\\CardDAV\\SystemAddressbook' => $baseDir . '/../lib/CardDAV/SystemAddressbook.php', 'OCA\\DAV\\CardDAV\\UserAddressBooks' => $baseDir . '/../lib/CardDAV/UserAddressBooks.php', + 'OCA\\DAV\\CardDAV\\Validation\\CardDavValidatePlugin' => $baseDir . '/../lib/CardDAV/Validation/CardDavValidatePlugin.php', 'OCA\\DAV\\CardDAV\\Xml\\Groups' => $baseDir . '/../lib/CardDAV/Xml/Groups.php', 'OCA\\DAV\\Command\\CreateAddressBook' => $baseDir . '/../lib/Command/CreateAddressBook.php', 'OCA\\DAV\\Command\\CreateCalendar' => $baseDir . '/../lib/Command/CreateCalendar.php', diff --git a/apps/dav/composer/composer/autoload_static.php b/apps/dav/composer/composer/autoload_static.php index 95d0808b8903e..c1bfc65179f4c 100644 --- a/apps/dav/composer/composer/autoload_static.php +++ b/apps/dav/composer/composer/autoload_static.php @@ -149,6 +149,7 @@ class ComposerStaticInitDAV 'OCA\\DAV\\CardDAV\\SyncService' => __DIR__ . '/..' . '/../lib/CardDAV/SyncService.php', 'OCA\\DAV\\CardDAV\\SystemAddressbook' => __DIR__ . '/..' . '/../lib/CardDAV/SystemAddressbook.php', 'OCA\\DAV\\CardDAV\\UserAddressBooks' => __DIR__ . '/..' . '/../lib/CardDAV/UserAddressBooks.php', + 'OCA\\DAV\\CardDAV\\Validation\\CardDavValidatePlugin' => __DIR__ . '/..' . '/../lib/CardDAV/Validation/CardDavValidatePlugin.php', 'OCA\\DAV\\CardDAV\\Xml\\Groups' => __DIR__ . '/..' . '/../lib/CardDAV/Xml/Groups.php', 'OCA\\DAV\\Command\\CreateAddressBook' => __DIR__ . '/..' . '/../lib/Command/CreateAddressBook.php', 'OCA\\DAV\\Command\\CreateCalendar' => __DIR__ . '/..' . '/../lib/Command/CreateCalendar.php', diff --git a/apps/dav/lib/CardDAV/Validation/CardDavValidatePlugin.php b/apps/dav/lib/CardDAV/Validation/CardDavValidatePlugin.php new file mode 100644 index 0000000000000..f53d5c54da9d2 --- /dev/null +++ b/apps/dav/lib/CardDAV/Validation/CardDavValidatePlugin.php @@ -0,0 +1,40 @@ +on('beforeMethod:PUT', [$this, 'beforePut']); + } + + public function beforePut(RequestInterface $request, ResponseInterface $response): bool { + // evaluate if card size exceeds defined limit + $cardSizeLimit = (int) $this->config->getAppValue(Application::APP_ID, 'card_size_limit', '5242880'); + if ((int) $request->getRawServerValue('CONTENT_LENGTH') > $cardSizeLimit) { + throw new Forbidden("VCard object exceeds $cardSizeLimit bytes"); + } + // all tests passed return true + return true; + } + +} diff --git a/apps/dav/lib/Server.php b/apps/dav/lib/Server.php index 3e76477b1f21c..f599865f1f562 100644 --- a/apps/dav/lib/Server.php +++ b/apps/dav/lib/Server.php @@ -45,6 +45,7 @@ use OCA\DAV\CardDAV\MultiGetExportPlugin; use OCA\DAV\CardDAV\PhotoCache; use OCA\DAV\CardDAV\Security\CardDavRateLimitingPlugin; +use OCA\DAV\CardDAV\Validation\CardDavValidatePlugin; use OCA\DAV\Comments\CommentsPlugin; use OCA\DAV\Connector\Sabre\AnonymousOptionsPlugin; use OCA\DAV\Connector\Sabre\Auth; @@ -213,6 +214,7 @@ public function __construct(IRequest $request, string $baseUri) { )); $this->server->addPlugin(\OCP\Server::get(CardDavRateLimitingPlugin::class)); + $this->server->addPlugin(\OCP\Server::get(CardDavValidatePlugin::class)); } // system tags plugins diff --git a/apps/dav/tests/unit/CardDAV/Validation/CardDavValidatePluginTest.php b/apps/dav/tests/unit/CardDAV/Validation/CardDavValidatePluginTest.php new file mode 100644 index 0000000000000..3c5f6ff20724d --- /dev/null +++ b/apps/dav/tests/unit/CardDAV/Validation/CardDavValidatePluginTest.php @@ -0,0 +1,73 @@ +config = $this->createMock(IConfig::class); + $this->request = $this->createMock(RequestInterface::class); + $this->response = $this->createMock(ResponseInterface::class); + $this->plugin = new CardDavValidatePlugin( + $this->config, + ); + } + + public function testPutSizeLessThenLimit(): void { + + // construct method responses + $this->config + ->method('getAppValue') + ->with('dav', 'card_size_limit', '5242880') + ->willReturn('5242880'); + $this->request + ->method('getRawServerValue') + ->with('CONTENT_LENGTH') + ->willReturn('1024'); + // test condition + $this->assertTrue( + $this->plugin->beforePut($this->request, $this->response) + ); + + } + + public function testPutSizeMoreThenLimit(): void { + + // construct method responses + $this->config + ->method('getAppValue') + ->with('dav', 'card_size_limit', '5242880') + ->willReturn('5242880'); + $this->request + ->method('getRawServerValue') + ->with('CONTENT_LENGTH') + ->willReturn('6242880'); + $this->expectException(Forbidden::class); + // test condition + $this->plugin->beforePut($this->request, $this->response); + + } + +}