diff --git a/config/config.sample.php b/config/config.sample.php index f9dd921033672..eeaa9a7ef3d92 100644 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -431,6 +431,17 @@ */ 'auth.bruteforce.protection.testing' => false, +/** + * Brute force protection: maximum number of attempts before blocking + * + * When more than max-attempts login requests are sent to Nextcloud, requests + * will abort with "429 Too Many Requests". + * For security reasons, change it only if you know what you are doing. + * + * Defaults to ``10`` + */ +'auth.bruteforce.max-attempts' => 10, + /** * Whether the rate limit protection shipped with Nextcloud should be enabled or not. * diff --git a/lib/private/Security/Bruteforce/Throttler.php b/lib/private/Security/Bruteforce/Throttler.php index 596fcf408fa8a..924ae3685f353 100644 --- a/lib/private/Security/Bruteforce/Throttler.php +++ b/lib/private/Security/Bruteforce/Throttler.php @@ -195,7 +195,7 @@ public function getDelay(string $ip, string $action = ''): int { } $firstDelay = 0.1; - if ($attempts > self::MAX_ATTEMPTS) { + if ($attempts > $this->config->getSystemValueInt('auth.bruteforce.max-attempts', self::MAX_ATTEMPTS)) { // Don't ever overflow. Just assume the maxDelay time:s return self::MAX_DELAY_MS; } @@ -263,7 +263,7 @@ public function sleepDelay(string $ip, string $action = ''): int { */ public function sleepDelayOrThrowOnMax(string $ip, string $action = ''): int { $delay = $this->getDelay($ip, $action); - if (($delay === self::MAX_DELAY_MS) && $this->getAttempts($ip, $action, 0.5) > self::MAX_ATTEMPTS) { + if (($delay === self::MAX_DELAY_MS) && $this->getAttempts($ip, $action, 0.5) > $this->config->getSystemValueInt('auth.bruteforce.max-attempts', self::MAX_ATTEMPTS)) { $this->logger->info('IP address blocked because it reached the maximum failed attempts in the last 30 minutes [action: {action}, ip: {ip}]', [ 'action' => $action, 'ip' => $ip,