Skip to content

Commit

Permalink
use bruteforce protection on all methods wrapped by PublicShareMiddle…
Browse files Browse the repository at this point in the history
…ware

if an invalid token is provided or when share password is wrong

Signed-off-by: Julien Veyssier <julien-nc@posteo.net>
  • Loading branch information
julien-nc committed Dec 7, 2022
1 parent 3f6415d commit 4a3f3be
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 3 deletions.
3 changes: 2 additions & 1 deletion lib/private/AppFramework/DependencyInjection/DIContainer.php
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,8 @@ public function __construct($appName, $urlParams = [], ServerContainer $server =
new OC\AppFramework\Middleware\PublicShare\PublicShareMiddleware(
$c->get(IRequest::class),
$c->get(ISession::class),
$c->get(\OCP\IConfig::class)
$c->get(\OCP\IConfig::class),
$c->get(OC\Security\Bruteforce\Throttler::class)
)
);
$dispatcher->registerMiddleware(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
namespace OC\AppFramework\Middleware\PublicShare;

use OC\AppFramework\Middleware\PublicShare\Exceptions\NeedAuthenticationException;
use OC\Security\Bruteforce\Throttler;
use OCP\AppFramework\AuthPublicShareController;
use OCP\AppFramework\Http\NotFoundResponse;
use OCP\AppFramework\Middleware;
Expand All @@ -34,6 +35,7 @@
use OCP\ISession;

class PublicShareMiddleware extends Middleware {

/** @var IRequest */
private $request;

Expand All @@ -43,17 +45,26 @@ class PublicShareMiddleware extends Middleware {
/** @var IConfig */
private $config;

public function __construct(IRequest $request, ISession $session, IConfig $config) {
/** @var Throttler */
private $throttler;

public function __construct(IRequest $request, ISession $session, IConfig $config, Throttler $throttler) {
$this->request = $request;
$this->session = $session;
$this->config = $config;
$this->throttler = $throttler;
}

public function beforeController($controller, $methodName) {
if (!($controller instanceof PublicShareController)) {
return;
}

$controllerClassPath = explode('\\', get_class($controller));
$controllerShortClass = end($controllerClassPath);
$bruteforceProtectionAction = $controllerShortClass . '::' . $methodName;
$this->throttler->sleepDelayOrThrowOnMax($this->request->getRemoteAddress(), $bruteforceProtectionAction);

if (!$this->isLinkSharingEnabled()) {
throw new NotFoundException('Link sharing is disabled');
}
Expand All @@ -68,6 +79,8 @@ public function beforeController($controller, $methodName) {
$controller->setToken($token);

if (!$controller->isValidToken()) {
$this->throttle($bruteforceProtectionAction, $token);

$controller->shareNotFound();
throw new NotFoundException();
}
Expand All @@ -88,6 +101,7 @@ public function beforeController($controller, $methodName) {
throw new NeedAuthenticationException();
}

$this->throttle($bruteforceProtectionAction, $token);
throw new NotFoundException();
}

Expand Down Expand Up @@ -128,4 +142,10 @@ private function isLinkSharingEnabled(): bool {

return true;
}

private function throttle($bruteforceProtectionAction, $token): void {
$ip = $this->request->getRemoteAddress();
$this->throttler->sleepDelay($ip, $bruteforceProtectionAction);
$this->throttler->registerAttempt($bruteforceProtectionAction, $ip, ['token' => $token]);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

use OC\AppFramework\Middleware\PublicShare\Exceptions\NeedAuthenticationException;
use OC\AppFramework\Middleware\PublicShare\PublicShareMiddleware;
use OC\Security\Bruteforce\Throttler;
use OCP\AppFramework\AuthPublicShareController;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\NotFoundResponse;
Expand All @@ -44,6 +45,8 @@ class PublicShareMiddlewareTest extends \Test\TestCase {
private $session;
/** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */
private $config;
/** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */
private $throttler;

/** @var PublicShareMiddleware */
private $middleware;
Expand All @@ -55,11 +58,13 @@ protected function setUp(): void {
$this->request = $this->createMock(IRequest::class);
$this->session = $this->createMock(ISession::class);
$this->config = $this->createMock(IConfig::class);
$this->throttler = $this->createMock(Throttler::class);

$this->middleware = new PublicShareMiddleware(
$this->request,
$this->session,
$this->config
$this->config,
$this->throttler
);
}

Expand Down

0 comments on commit 4a3f3be

Please sign in to comment.