diff options
author | Lukas Reschke <lukas@statuscode.ch> | 2021-06-22 20:54:13 +0300 |
---|---|---|
committer | Lukas Reschke <lukas@statuscode.ch> | 2021-06-22 20:54:13 +0300 |
commit | d6a2f00befda97f25f13dae8c11be75077a358a2 (patch) | |
tree | 5709e207533f0dcdeda18541dee21ec4eb4ba7a6 | |
parent | 1c8f5cbc8275606d290d0ce56fb329f3106ee7f6 (diff) |
Throttle on public DAV endpoint
We should throttle whenever an invalid request is sent to the public WebDAV endpoint.
Signed-off-by: Lukas Reschke <lukas@statuscode.ch>
-rw-r--r-- | apps/dav/appinfo/v1/publicwebdav.php | 3 | ||||
-rw-r--r-- | apps/dav/lib/Connector/PublicAuth.php | 16 | ||||
-rw-r--r-- | apps/dav/tests/unit/Connector/PublicAuthTest.php | 9 |
3 files changed, 25 insertions, 3 deletions
diff --git a/apps/dav/appinfo/v1/publicwebdav.php b/apps/dav/appinfo/v1/publicwebdav.php index b0b87c66ca6..c99c5bcd833 100644 --- a/apps/dav/appinfo/v1/publicwebdav.php +++ b/apps/dav/appinfo/v1/publicwebdav.php @@ -41,7 +41,8 @@ OC_Util::obEnd(); $authBackend = new OCA\DAV\Connector\PublicAuth( \OC::$server->getRequest(), \OC::$server->getShareManager(), - \OC::$server->getSession() + \OC::$server->getSession(), + \OC::$server->getBruteForceThrottler() ); $authPlugin = new \Sabre\DAV\Auth\Plugin($authBackend); diff --git a/apps/dav/lib/Connector/PublicAuth.php b/apps/dav/lib/Connector/PublicAuth.php index 55d2de72228..426cbf871d7 100644 --- a/apps/dav/lib/Connector/PublicAuth.php +++ b/apps/dav/lib/Connector/PublicAuth.php @@ -29,6 +29,7 @@ */ namespace OCA\DAV\Connector; +use OC\Security\Bruteforce\Throttler; use OCP\IRequest; use OCP\ISession; use OCP\Share\Exceptions\ShareNotFound; @@ -42,6 +43,7 @@ use Sabre\DAV\Auth\Backend\AbstractBasic; * @package OCA\DAV\Connector */ class PublicAuth extends AbstractBasic { + private const BRUTEFORCE_ACTION = 'public_webdav_auth'; /** @var \OCP\Share\IShare */ private $share; @@ -55,17 +57,23 @@ class PublicAuth extends AbstractBasic { /** @var IRequest */ private $request; + /** @var Throttler */ + private $throttler; + /** * @param IRequest $request * @param IManager $shareManager * @param ISession $session + * @param Throttler $throttler */ public function __construct(IRequest $request, IManager $shareManager, - ISession $session) { + ISession $session, + Throttler $throttler) { $this->request = $request; $this->shareManager = $shareManager; $this->session = $session; + $this->throttler = $throttler; // setup realm $defaults = new \OCP\Defaults(); @@ -85,9 +93,12 @@ class PublicAuth extends AbstractBasic { * @throws \Sabre\DAV\Exception\NotAuthenticated */ protected function validateUserPass($username, $password) { + $this->throttler->sleepDelayOrThrowOnMax($this->request->getRemoteAddress(), self::BRUTEFORCE_ACTION); + try { $share = $this->shareManager->getShareByToken($username); } catch (ShareNotFound $e) { + $this->throttler->registerAttempt(self::BRUTEFORCE_ACTION, $this->request->getRemoteAddress()); return false; } @@ -112,11 +123,14 @@ class PublicAuth extends AbstractBasic { header('WWW-Authenticate: DummyBasic realm="' . $this->realm . '"'); throw new \Sabre\DAV\Exception\NotAuthenticated('Cannot authenticate over ajax calls'); } + + $this->throttler->registerAttempt(self::BRUTEFORCE_ACTION, $this->request->getRemoteAddress()); return false; } } elseif ($share->getShareType() === IShare::TYPE_REMOTE) { return true; } else { + $this->throttler->registerAttempt(self::BRUTEFORCE_ACTION, $this->request->getRemoteAddress()); return false; } } else { diff --git a/apps/dav/tests/unit/Connector/PublicAuthTest.php b/apps/dav/tests/unit/Connector/PublicAuthTest.php index cdf269deb33..2d06e8dd615 100644 --- a/apps/dav/tests/unit/Connector/PublicAuthTest.php +++ b/apps/dav/tests/unit/Connector/PublicAuthTest.php @@ -26,6 +26,7 @@ */ namespace OCA\DAV\Tests\unit\Connector; +use OC\Security\Bruteforce\Throttler; use OCP\IRequest; use OCP\ISession; use OCP\Share\Exceptions\ShareNotFound; @@ -49,6 +50,8 @@ class PublicAuthTest extends \Test\TestCase { private $shareManager; /** @var \OCA\DAV\Connector\PublicAuth */ private $auth; + /** @var Throttler|\PHPUnit\Framework\MockObject\MockObject */ + private $throttler; /** @var string */ private $oldUser; @@ -65,11 +68,15 @@ class PublicAuthTest extends \Test\TestCase { $this->shareManager = $this->getMockBuilder(IManager::class) ->disableOriginalConstructor() ->getMock(); + $this->shareManager = $this->getMockBuilder(Throttler::class) + ->disableOriginalConstructor() + ->getMock(); $this->auth = new \OCA\DAV\Connector\PublicAuth( $this->request, $this->shareManager, - $this->session + $this->session, + $this->throttler ); // Store current user |