diff options
Diffstat (limited to 'lib/public/Security')
22 files changed, 515 insertions, 289 deletions
diff --git a/lib/public/Security/Bruteforce/IThrottler.php b/lib/public/Security/Bruteforce/IThrottler.php new file mode 100644 index 00000000000..502e9d2e88b --- /dev/null +++ b/lib/public/Security/Bruteforce/IThrottler.php @@ -0,0 +1,138 @@ +<?php + +declare(strict_types=1); +/** + * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +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 + * @deprecated 28.0.0 + */ + public const MAX_DELAY = 25; + + /** + * @since 25.0.0 + * @deprecated 28.0.0 + */ + public const MAX_DELAY_MS = 25000; // in milliseconds + + /** + * @since 25.0.0 + * @deprecated 28.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 with the attempt + * @since 25.0.0 + */ + public function registerAttempt(string $action, string $ip, array $metadata = []): void; + + + /** + * Check if the IP is allowed to bypass the brute force protection + * + * @param string $ip + * @return bool + * @since 28.0.0 + */ + public function isBypassListed(string $ip): bool; + + /** + * 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 + * @deprecated 28.0.0 This method is considered internal as of Nextcloud 28. Use {@see showBruteforceWarning()} to decide whether a warning should be shown. + */ + public function getAttempts(string $ip, string $action = '', float $maxAgeHours = 12): int; + + /** + * Whether a warning should be shown about the throttle + * + * @param string $ip + * @param string $action optionally filter by action + * @return bool + * @since 28.0.0 + */ + public function showBruteforceWarning(string $ip, string $action = ''): bool; + + /** + * Get the throttling delay (in milliseconds) + * + * @param string $ip + * @param string $action optionally filter by action + * @return int + * @since 25.0.0 + * @deprecated 28.0.0 This method is considered internal as of Nextcloud 28. Use {@see showBruteforceWarning()} to decide whether a warning should be shown. + */ + 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 + * @deprecated 28.0.0 This method is considered internal as of Nextcloud 28. Use {@see resetDelay()} and only reset the entries of your action and metadata + */ + 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 + * @deprecated 28.0.0 Use {@see sleepDelayOrThrowOnMax()} instead and abort handling the request when it throws + */ + 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; +} diff --git a/lib/public/Security/Bruteforce/MaxDelayReached.php b/lib/public/Security/Bruteforce/MaxDelayReached.php index eaac4edbd1b..b44112c5f04 100644 --- a/lib/public/Security/Bruteforce/MaxDelayReached.php +++ b/lib/public/Security/Bruteforce/MaxDelayReached.php @@ -3,25 +3,8 @@ declare(strict_types=1); /** - * @copyright Copyright (c) 2020 Joas Schilling <coding@schilljs.com> - * - * @author 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/>. - * + * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace OCP\Security\Bruteforce; diff --git a/lib/public/Security/CSP/AddContentSecurityPolicyEvent.php b/lib/public/Security/CSP/AddContentSecurityPolicyEvent.php index 13aeab8bf44..c1cbddd298f 100644 --- a/lib/public/Security/CSP/AddContentSecurityPolicyEvent.php +++ b/lib/public/Security/CSP/AddContentSecurityPolicyEvent.php @@ -3,27 +3,8 @@ declare(strict_types=1); /** - * @copyright Copyright (c) 2019, Roeland Jago Douma <roeland@famdouma.nl> - * - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @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/>. - * + * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace OCP\Security\CSP; @@ -45,7 +26,6 @@ use OCP\EventDispatcher\Event; * @since 17.0.0 */ class AddContentSecurityPolicyEvent extends Event { - /** @var ContentSecurityPolicyManager */ private $policyManager; diff --git a/lib/public/Security/Events/GenerateSecurePasswordEvent.php b/lib/public/Security/Events/GenerateSecurePasswordEvent.php index 6897cb1ee91..419e7b40ee4 100644 --- a/lib/public/Security/Events/GenerateSecurePasswordEvent.php +++ b/lib/public/Security/Events/GenerateSecurePasswordEvent.php @@ -3,39 +3,40 @@ declare(strict_types=1); /** - * @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at> - * - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * - * @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/>. - * + * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace OCP\Security\Events; use OCP\EventDispatcher\Event; +use OCP\Security\PasswordContext; /** + * Event to request a secure password to be generated * @since 18.0.0 */ class GenerateSecurePasswordEvent extends Event { + private ?string $password; - /** @var null|string */ - private $password; + /** + * Request a secure password to be generated. + * + * By default passwords are generated for the user account context, + * this can be adjusted by passing another `PasswordContext`. + * @since 31.0.0 + */ + public function __construct( + private PasswordContext $context = PasswordContext::ACCOUNT, + ) { + parent::__construct(); + $this->password = null; + } /** + * Get the generated password. + * + * If a password generator is registered and successfully generated a password + * that password can get read back. Otherwise `null` is returned. * @since 18.0.0 */ public function getPassword(): ?string { @@ -43,9 +44,20 @@ class GenerateSecurePasswordEvent extends Event { } /** + * Set the generated password. + * + * This is used by password generators to set the generated password. * @since 18.0.0 */ public function setPassword(string $password): void { $this->password = $password; } + + /** + * Get the context this password should generated for. + * @since 31.0.0 + */ + public function getContext(): PasswordContext { + return $this->context; + } } diff --git a/lib/public/Security/Events/ValidatePasswordPolicyEvent.php b/lib/public/Security/Events/ValidatePasswordPolicyEvent.php index efe420d3cf2..d7ac9442392 100644 --- a/lib/public/Security/Events/ValidatePasswordPolicyEvent.php +++ b/lib/public/Security/Events/ValidatePasswordPolicyEvent.php @@ -3,50 +3,47 @@ declare(strict_types=1); /** - * @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at> - * - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * - * @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/>. - * + * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace OCP\Security\Events; use OCP\EventDispatcher\Event; +use OCP\Security\PasswordContext; /** + * This event can be emitted to request a validation of a password. + * + * If a password policy app is installed and the password + * is invalid, an `\OCP\HintException` will be thrown. * @since 18.0.0 */ class ValidatePasswordPolicyEvent extends Event { - /** @var string */ - private $password; - /** * @since 18.0.0 + * @since 31.0.0 - $context parameter added */ - public function __construct(string $password) { + public function __construct( + private string $password, + private PasswordContext $context = PasswordContext::ACCOUNT, + ) { parent::__construct(); - $this->password = $password; } /** + * Get the password that should be validated. * @since 18.0.0 */ public function getPassword(): string { return $this->password; } + + /** + * Get the context this password should validated for. + * @since 31.0.0 + */ + public function getContext(): PasswordContext { + return $this->context; + } } diff --git a/lib/public/Security/FeaturePolicy/AddFeaturePolicyEvent.php b/lib/public/Security/FeaturePolicy/AddFeaturePolicyEvent.php index a0478ad56fe..c89c11bf7cd 100644 --- a/lib/public/Security/FeaturePolicy/AddFeaturePolicyEvent.php +++ b/lib/public/Security/FeaturePolicy/AddFeaturePolicyEvent.php @@ -3,27 +3,8 @@ declare(strict_types=1); /** - * @copyright Copyright (c) 2019, Roeland Jago Douma <roeland@famdouma.nl> - * - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @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/>. - * + * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace OCP\Security\FeaturePolicy; @@ -37,7 +18,6 @@ use OCP\EventDispatcher\Event; * @since 17.0.0 */ class AddFeaturePolicyEvent extends Event { - /** @var FeaturePolicyManager */ private $policyManager; diff --git a/lib/public/Security/IContentSecurityPolicyManager.php b/lib/public/Security/IContentSecurityPolicyManager.php index 878527bc4be..00cdcc2c454 100644 --- a/lib/public/Security/IContentSecurityPolicyManager.php +++ b/lib/public/Security/IContentSecurityPolicyManager.php @@ -1,28 +1,10 @@ <?php declare(strict_types=1); - /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Lukas Reschke <lukas@statuscode.ch> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * 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, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCP\Security; @@ -42,7 +24,7 @@ interface IContentSecurityPolicyManager { * Note that the adjustment is only applied to applications that use AppFramework * controllers. * - * To use this from your `app.php` use `\OC::$server->getContentSecurityPolicyManager()->addDefaultPolicy($policy)`, + * To use this from your `app.php` use `\OCP\Server::get(IContentSecurityPolicyManager::class)->addDefaultPolicy($policy)`, * $policy has to be of type `\OCP\AppFramework\Http\ContentSecurityPolicy`. * * WARNING: Using this API incorrectly may make the instance more insecure. diff --git a/lib/public/Security/ICredentialsManager.php b/lib/public/Security/ICredentialsManager.php index 7ac0d705a77..7b24eb7e7a2 100644 --- a/lib/public/Security/ICredentialsManager.php +++ b/lib/public/Security/ICredentialsManager.php @@ -1,28 +1,10 @@ <?php declare(strict_types=1); - /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Arthur Schiwon <blizzz@arthur-schiwon.de> - * @author J0WI <J0WI@users.noreply.github.com> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * 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, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCP\Security; @@ -32,7 +14,6 @@ namespace OCP\Security; * @since 8.2.0 */ interface ICredentialsManager { - /** * Store a set of credentials * diff --git a/lib/public/Security/ICrypto.php b/lib/public/Security/ICrypto.php index 2ca501e62be..78b0fc14d6d 100644 --- a/lib/public/Security/ICrypto.php +++ b/lib/public/Security/ICrypto.php @@ -1,28 +1,10 @@ <?php declare(strict_types=1); - /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Lukas Reschke <lukas@statuscode.ch> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * 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, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCP\Security; @@ -31,13 +13,12 @@ namespace OCP\Security; * it will use the secret defined in config.php as key. Additionally the message will be HMAC'd. * * Usage: - * $encryptWithDefaultPassword = \OC::$server->getCrypto()->encrypt('EncryptedText'); - * $encryptWithCustomPassword = \OC::$server->getCrypto()->encrypt('EncryptedText', 'password'); + * $encryptWithDefaultPassword = \OCP\Server::get(ICrypto::class)->encrypt('EncryptedText'); + * $encryptWithCustomPassword = \OCP\Server::get(ICrypto::class)->encrypt('EncryptedText', 'password'); * * @since 8.0.0 */ interface ICrypto { - /** * @param string $message The message to authenticate * @param string $password Password to use (defaults to `secret` in config.php) diff --git a/lib/public/Security/IHasher.php b/lib/public/Security/IHasher.php index 7c4d743002c..d0d6e4e9028 100644 --- a/lib/public/Security/IHasher.php +++ b/lib/public/Security/IHasher.php @@ -1,28 +1,10 @@ <?php declare(strict_types=1); - /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Lukas Reschke <lukas@statuscode.ch> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * 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, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCP\Security; @@ -37,10 +19,10 @@ namespace OCP\Security; * * Usage: * // Hashing a message - * $hash = \OC::$server->getHasher()->hash('MessageToHash'); + * $hash = \OCP\Server::get(\OCP\Security\IHasher::class)->hash('MessageToHash'); * // Verifying a message - $newHash will contain the newly calculated hash * $newHash = null; - * var_dump(\OC::$server->getHasher()->verify('a', '86f7e437faa5a7fce15d1ddcb9eaeaea377667b8', $newHash)); + * var_dump(\OCP\Server::get(\OCP\Security\IHasher::class)->verify('a', '86f7e437faa5a7fce15d1ddcb9eaeaea377667b8', $newHash)); * var_dump($newHash); * * @since 8.0.0 @@ -65,4 +47,11 @@ interface IHasher { * @since 8.0.0 */ public function verify(string $message, string $hash, &$newHash = null): bool ; + + /** + * Check if the prefixed hash is valid + * + * @since 30.0.0 + */ + public function validate(string $prefixedHash): bool; } diff --git a/lib/public/Security/IRemoteHostValidator.php b/lib/public/Security/IRemoteHostValidator.php new file mode 100644 index 00000000000..0707a633073 --- /dev/null +++ b/lib/public/Security/IRemoteHostValidator.php @@ -0,0 +1,32 @@ +<?php + +declare(strict_types=1); +/** + * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ +namespace OCP\Security; + +/** + * Validator for remote hosts + * + * @since 26.0.0 + */ +interface IRemoteHostValidator { + /** + * Validate if a host may be connected to + * + * By default, Nextcloud does not connect to any local servers. That is neither + * localhost nor any host in the local network. + * + * Admins can overwrite this behavior with the global `allow_local_remote_servers` + * settings flag. If the flag is set to `true`, local hosts will be considered + * valid. + * + * @param string $host hostname of the remote server, IPv4 or IPv6 address + * + * @return bool + * @since 26.0.0 + */ + public function isValid(string $host): bool; +} diff --git a/lib/public/Security/ISecureRandom.php b/lib/public/Security/ISecureRandom.php index 250ecd25358..0f4a79e08e0 100644 --- a/lib/public/Security/ISecureRandom.php +++ b/lib/public/Security/ISecureRandom.php @@ -1,30 +1,10 @@ <?php declare(strict_types=1); - /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Fabrizio Steiner <fabrizio.steiner@gmail.com> - * @author Lukas Reschke <lukas@statuscode.ch> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * 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, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCP\Security; @@ -34,25 +14,43 @@ namespace OCP\Security; * use a fallback. * * Usage: - * \OC::$server->getSecureRandom()->generate(10); + * \OCP\Server::get(ISecureRandom::class)->generate(10); * * @since 8.0.0 */ interface ISecureRandom { - /** * Flags for characters that can be used for <code>generate($length, $characters)</code> + * @since 8.0.0 */ public const CHAR_UPPER = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; + + /** + * @since 8.0.0 + */ public const CHAR_LOWER = 'abcdefghijklmnopqrstuvwxyz'; + + /** + * @since 8.0.0 + */ public const CHAR_DIGITS = '0123456789'; + + /** + * @since 8.0.0 + */ public const CHAR_SYMBOLS = '!\"#$%&\\\'()*+,-./:;<=>?@[\]^_`{|}~'; + + /** + * @since 12.0.0 + */ public const CHAR_ALPHANUMERIC = self::CHAR_UPPER . self::CHAR_LOWER . self::CHAR_DIGITS; /** * Characters that can be used for <code>generate($length, $characters)</code>, to - * generate human readable random strings. Lower- and upper-case characters and digits + * generate human-readable random strings. Lower- and upper-case characters and digits * are included. Characters which are ambiguous are excluded, such as I, l, and 1 and so on. + * + * @since 23.0.0 */ public const CHAR_HUMAN_READABLE = 'abcdefgijkmnopqrstwxyzABCDEFGHJKLMNPQRSTWXYZ23456789'; @@ -60,10 +58,10 @@ interface ISecureRandom { * Generate a random string of specified length. * @param int $length The length of the generated string * @param string $characters An optional list of characters to use if no character list is - * specified all valid base64 characters are used. + * specified all valid base64 characters are used. * @return string * @since 8.0.0 */ public function generate(int $length, - string $characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'): string; + string $characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'): string; } diff --git a/lib/public/Security/ITrustedDomainHelper.php b/lib/public/Security/ITrustedDomainHelper.php index 4737625b6e8..01edf57e6f3 100644 --- a/lib/public/Security/ITrustedDomainHelper.php +++ b/lib/public/Security/ITrustedDomainHelper.php @@ -2,25 +2,9 @@ declare(strict_types=1); /** - * @copyright Copyright (c) 2021 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/>. - * + * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ - namespace OCP\Security; /** diff --git a/lib/public/Security/Ip/IAddress.php b/lib/public/Security/Ip/IAddress.php new file mode 100644 index 00000000000..bff7744ddce --- /dev/null +++ b/lib/public/Security/Ip/IAddress.php @@ -0,0 +1,35 @@ +<?php + +declare(strict_types=1); +/** + * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace OCP\Security\Ip; + +/** + * @since 30.0.0 + */ +interface IAddress { + /** + * Check if a given IP address is valid + * + * @since 30.0.0 + */ + public static function isValid(string $ip): bool; + + /** + * Check if current address is contained by given ranges + * + * @since 30.0.0 + */ + public function matches(IRange ... $ranges): bool; + + /** + * Normalized IP address + * + * @since 30.0.0 + */ + public function __toString(): string; +} diff --git a/lib/public/Security/Ip/IFactory.php b/lib/public/Security/Ip/IFactory.php new file mode 100644 index 00000000000..3b88aa8c756 --- /dev/null +++ b/lib/public/Security/Ip/IFactory.php @@ -0,0 +1,30 @@ +<?php + +declare(strict_types=1); +/** + * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace OCP\Security\Ip; + +/** + * @since 30.0.0 + */ +interface IFactory { + /** + * Creates a range from string + * + * @since 30.0.0 + * @throws \InvalidArgumentException on invalid range + */ + public function rangeFromString(string $range): IRange; + + /** + * Creates a address from string + * + * @since 30.0.0 + * @throws \InvalidArgumentException on invalid IP + */ + public function addressFromString(string $ip): IAddress; +} diff --git a/lib/public/Security/Ip/IRange.php b/lib/public/Security/Ip/IRange.php new file mode 100644 index 00000000000..70e1815c75e --- /dev/null +++ b/lib/public/Security/Ip/IRange.php @@ -0,0 +1,37 @@ +<?php + +declare(strict_types=1); +/** + * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace OCP\Security\Ip; + +/** + * IP Range (IPv4 or IPv6) + * + * @since 30.0.0 + */ +interface IRange { + /** + * Check if a given range is valid + * + * @since 30.0.0 + */ + public static function isValid(string $range): bool; + + /** + * Check if an address is in the current range + * + * @since 30.0.0 + */ + public function contains(IAddress $address): bool; + + /** + * Normalized IP range + * + * @since 30.0.0 + */ + public function __toString(): string; +} diff --git a/lib/public/Security/Ip/IRemoteAddress.php b/lib/public/Security/Ip/IRemoteAddress.php new file mode 100644 index 00000000000..19a1dab9734 --- /dev/null +++ b/lib/public/Security/Ip/IRemoteAddress.php @@ -0,0 +1,22 @@ +<?php + +declare(strict_types=1); +/** + * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace OCP\Security\Ip; + +/** + * IP address of the connected client + * + * @since 30.0.0 + */ +interface IRemoteAddress { + /** + * Check if the current remote address is allowed to perform admin actions + * @since 30.0.0 + */ + public function allowsAdminActions(): bool; +} diff --git a/lib/public/Security/PasswordContext.php b/lib/public/Security/PasswordContext.php new file mode 100644 index 00000000000..909070c09ff --- /dev/null +++ b/lib/public/Security/PasswordContext.php @@ -0,0 +1,29 @@ +<?php + +declare(strict_types=1); +/** + * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ +namespace OCP\Security; + +/** + * Define the context in which a password is used. + * This allows setting a context for password validation and password generation. + * + * @package OCP\Security + * @since 31.0.0 + */ +enum PasswordContext { + /** + * Password used for an user account + * @since 31.0.0 + */ + case ACCOUNT; + + /** + * Password used for (public) shares + * @since 31.0.0 + */ + case SHARING; +} diff --git a/lib/public/Security/RateLimiting/ILimiter.php b/lib/public/Security/RateLimiting/ILimiter.php new file mode 100644 index 00000000000..22a07f3d430 --- /dev/null +++ b/lib/public/Security/RateLimiting/ILimiter.php @@ -0,0 +1,56 @@ +<?php + +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace OCP\Security\RateLimiting; + +use OCP\AppFramework\Http\Attribute\AnonRateLimit; +use OCP\AppFramework\Http\Attribute\UserRateLimit; +use OCP\IUser; + +/** + * Programmatic rate limiter for web requests that are not handled by an app framework controller + * + * @see AnonRateLimit + * @see UserRateLimit + * + * @since 28.0.0 + */ +interface ILimiter { + /** + * Registers attempt for an anonymous request + * + * @param string $identifier + * @param int $anonLimit + * @param int $anonPeriod in seconds + * @param string $ip + * @throws IRateLimitExceededException if limits are reached, which should cause a HTTP 429 response + * @since 28.0.0 + * + */ + public function registerAnonRequest(string $identifier, + int $anonLimit, + int $anonPeriod, + string $ip): void; + + /** + * Registers attempt for an authenticated request + * + * @param string $identifier + * @param int $userLimit + * @param int $userPeriod in seconds + * @param IUser $user the acting user + * @throws IRateLimitExceededException if limits are reached, which should cause a HTTP 429 response + * @since 28.0.0 + * + */ + public function registerUserRequest(string $identifier, + int $userLimit, + int $userPeriod, + IUser $user): void; +} diff --git a/lib/public/Security/RateLimiting/IRateLimitExceededException.php b/lib/public/Security/RateLimiting/IRateLimitExceededException.php new file mode 100644 index 00000000000..897e0cc833e --- /dev/null +++ b/lib/public/Security/RateLimiting/IRateLimitExceededException.php @@ -0,0 +1,20 @@ +<?php + +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace OCP\Security\RateLimiting; + +use Throwable; + +/** + * Thrown if the (anonymous) user has exceeded a rate limit + * + * @since 28.0.0 + */ +interface IRateLimitExceededException extends Throwable { +} diff --git a/lib/public/Security/VerificationToken/IVerificationToken.php b/lib/public/Security/VerificationToken/IVerificationToken.php index e1d9203ec3b..519fbd1bbed 100644 --- a/lib/public/Security/VerificationToken/IVerificationToken.php +++ b/lib/public/Security/VerificationToken/IVerificationToken.php @@ -1,29 +1,10 @@ <?php declare(strict_types=1); - /** - * @copyright Copyright (c) 2021 Arthur Schiwon <blizzz@arthur-schiwon.de> - * - * @author Arthur Schiwon <blizzz@arthur-schiwon.de> - * - * @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 <https://www.gnu.org/licenses/>. - * + * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ - namespace OCP\Security\VerificationToken; use OCP\IUser; @@ -32,7 +13,6 @@ use OCP\IUser; * @since 23.0.0 */ interface IVerificationToken { - /** * Checks whether the a provided tokent matches a stored token and its * constraints. An InvalidTokenException is thrown on issues, otherwise diff --git a/lib/public/Security/VerificationToken/InvalidTokenException.php b/lib/public/Security/VerificationToken/InvalidTokenException.php index 5c8144c5c74..a84f8817350 100644 --- a/lib/public/Security/VerificationToken/InvalidTokenException.php +++ b/lib/public/Security/VerificationToken/InvalidTokenException.php @@ -1,34 +1,14 @@ <?php declare(strict_types=1); - /** - * @copyright Copyright (c) 2021 Arthur Schiwon <blizzz@arthur-schiwon.de> - * - * @author Arthur Schiwon <blizzz@arthur-schiwon.de> - * - * @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 <https://www.gnu.org/licenses/>. - * + * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ - namespace OCP\Security\VerificationToken; /** @since 23.0.0 */ class InvalidTokenException extends \Exception { - /** * @since 23.0.0 */ |