Skip to content

Commit

Permalink
Merge pull request #35652 from nextcloud/backport/35057/stable23
Browse files Browse the repository at this point in the history
[stable23] Add brute force protection on all methods wrapped by PublicShareMiddleware
  • Loading branch information
julien-nc authored Mar 15, 2023
2 parents d78baf4 + b384a96 commit 9681be3
Show file tree
Hide file tree
Showing 3 changed files with 26 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 @@ -299,7 +299,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 @@ -42,18 +43,26 @@ class PublicShareMiddleware extends Middleware {

/** @var IConfig */
private $config;
/** @var Throttler */
private $throttler;

public function __construct(IRequest $request, ISession $session, IConfig $config) {
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 @@ -79,6 +88,7 @@ public function beforeController($controller, $methodName) {

// If authentication succeeds just continue
if ($controller->isAuthenticated()) {
$this->throttle($bruteforceProtectionAction, $token);
return;
}

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

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

Expand Down Expand Up @@ -128,4 +139,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 Throttler|\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 9681be3

Please sign in to comment.