Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/server.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoas Schilling <coding@schilljs.com>2022-07-01 12:18:27 +0300
committerJoas Schilling <coding@schilljs.com>2022-07-28 11:57:10 +0300
commitc0f47af2d04f4417d8f9792649266d5dd7a60a59 (patch)
tree6ccef5eeb05cdb33fd468b881e8277ff37875a95 /lib/public
parent472f4cad47f832ac0807ac3c4aa33d60a5bcbf31 (diff)
Add a public interface for the bruteforce throttler and register for injection
Signed-off-by: Joas Schilling <coding@schilljs.com>
Diffstat (limited to 'lib/public')
-rw-r--r--lib/public/Security/Bruteforce/IThrottler.php126
1 files changed, 126 insertions, 0 deletions
diff --git a/lib/public/Security/Bruteforce/IThrottler.php b/lib/public/Security/Bruteforce/IThrottler.php
new file mode 100644
index 00000000000..6f492d6c59d
--- /dev/null
+++ b/lib/public/Security/Bruteforce/IThrottler.php
@@ -0,0 +1,126 @@
+<?php
+
+declare(strict_types=1);
+/**
+ * @copyright Copyright (c) 2022 Joas Schilling <coding@schilljs.com>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCP\Security\Bruteforce;
+
+/**
+ * Class Throttler implements the bruteforce protection for security actions in
+ * Nextcloud.
+ *
+ * It is working by logging invalid login attempts to the database and slowing
+ * down all login attempts from the same subnet. The max delay is 30 seconds and
+ * the starting delay are 200 milliseconds. (after the first failed login)
+ *
+ * This is based on Paragonie's AirBrake for Airship CMS. You can find the original
+ * code at https://github.com/paragonie/airship/blob/7e5bad7e3c0fbbf324c11f963fd1f80e59762606/src/Engine/Security/AirBrake.php
+ *
+ * @package OC\Security\Bruteforce
+ * @since 25.0.0
+ */
+interface IThrottler {
+ /**
+ * @since 25.0.0
+ */
+ public const MAX_DELAY = 25;
+
+ /**
+ * @since 25.0.0
+ */
+ public const MAX_DELAY_MS = 25000; // in milliseconds
+
+ /**
+ * @since 25.0.0
+ */
+ public const MAX_ATTEMPTS = 10;
+
+ /**
+ * Register a failed attempt to bruteforce a security control
+ *
+ * @param string $action
+ * @param string $ip
+ * @param array $metadata Optional metadata logged to the database
+ * @since 25.0.0
+ */
+ public function registerAttempt(string $action, string $ip, array $metadata = []): void;
+
+ /**
+ * Get the throttling delay (in milliseconds)
+ *
+ * @param string $ip
+ * @param string $action optionally filter by action
+ * @param float $maxAgeHours
+ * @return int
+ * @since 25.0.0
+ */
+ public function getAttempts(string $ip, string $action = '', float $maxAgeHours = 12): int;
+
+ /**
+ * Get the throttling delay (in milliseconds)
+ *
+ * @param string $ip
+ * @param string $action optionally filter by action
+ * @return int
+ * @since 25.0.0
+ */
+ public function getDelay(string $ip, string $action = ''): int;
+
+ /**
+ * Reset the throttling delay for an IP address, action and metadata
+ *
+ * @param string $ip
+ * @param string $action
+ * @param array $metadata
+ * @since 25.0.0
+ */
+ public function resetDelay(string $ip, string $action, array $metadata): void;
+
+ /**
+ * Reset the throttling delay for an IP address
+ *
+ * @param string $ip
+ * @since 25.0.0
+ */
+ public function resetDelayForIP(string $ip): void;
+
+ /**
+ * Will sleep for the defined amount of time
+ *
+ * @param string $ip
+ * @param string $action optionally filter by action
+ * @return int the time spent sleeping
+ * @since 25.0.0
+ */
+ public function sleepDelay(string $ip, string $action = ''): int;
+
+ /**
+ * Will sleep for the defined amount of time unless maximum was reached in the last 30 minutes
+ * In this case a "429 Too Many Request" exception is thrown
+ *
+ * @param string $ip
+ * @param string $action optionally filter by action
+ * @return int the time spent sleeping
+ * @throws MaxDelayReached when reached the maximum
+ * @since 25.0.0
+ */
+ public function sleepDelayOrThrowOnMax(string $ip, string $action = ''): int;
+}