]> source.dussan.org Git - nextcloud-server.git/commitdiff
feat(admin): Show an error when the admin is throttled
authorJoas Schilling <coding@schilljs.com>
Thu, 17 Aug 2023 06:45:46 +0000 (08:45 +0200)
committerJoas Schilling <coding@schilljs.com>
Wed, 23 Aug 2023 04:44:08 +0000 (06:44 +0200)
Signed-off-by: Joas Schilling <coding@schilljs.com>
apps/settings/lib/Controller/CheckSetupController.php
apps/settings/tests/Controller/CheckSetupControllerTest.php
core/js/setupchecks.js
core/js/tests/specs/setupchecksSpec.js

index a55596358e5dc61707d635c468c73c9f8c251648..29ef0343399c11b0291c7b20f0654a4ca0892714 100644 (file)
@@ -86,6 +86,7 @@ use OCP\ITempManager;
 use OCP\IURLGenerator;
 use OCP\Lock\ILockingProvider;
 use OCP\Notification\IManager;
+use OCP\Security\Bruteforce\IThrottler;
 use OCP\Security\ISecureRandom;
 use Psr\Log\LoggerInterface;
 use Symfony\Component\EventDispatcher\EventDispatcherInterface;
@@ -122,6 +123,8 @@ class CheckSetupController extends Controller {
        private $iniGetWrapper;
        /** @var IDBConnection */
        private $connection;
+       /** @var IThrottler */
+       private $throttler;
        /** @var ITempManager */
        private $tempManager;
        /** @var IManager */
@@ -148,6 +151,7 @@ class CheckSetupController extends Controller {
                                                                ISecureRandom $secureRandom,
                                                                IniGetWrapper $iniGetWrapper,
                                                                IDBConnection $connection,
+                                                               IThrottler $throttler,
                                                                ITempManager $tempManager,
                                                                IManager $manager,
                                                                IAppManager $appManager,
@@ -163,6 +167,7 @@ class CheckSetupController extends Controller {
                $this->eventDispatcher = $eventDispatcher;
                $this->dispatcher = $dispatcher;
                $this->db = $db;
+               $this->throttler = $throttler;
                $this->lockingProvider = $lockingProvider;
                $this->dateTimeFormatter = $dateTimeFormatter;
                $this->memoryInfo = $memoryInfo;
@@ -909,6 +914,8 @@ Raw output
                                'cronInfo' => $this->getLastCronInfo(),
                                'cronErrors' => $this->getCronErrors(),
                                'isFairUseOfFreePushService' => $this->isFairUseOfFreePushService(),
+                               'isBruteforceThrottled' => $this->throttler->getAttempts($this->request->getRemoteAddress()) !== 0,
+                               'bruteforceRemoteAddress' => $this->request->getRemoteAddress(),
                                'serverHasInternetConnectionProblems' => $this->hasInternetConnectivityProblems(),
                                'isMemcacheConfigured' => $this->isMemcacheConfigured(),
                                'memcacheDocs' => $this->urlGenerator->linkToDocs('admin-performance'),
index 390166cb947ed98634c0dec045d0c705ff88a6d7..2d2d43434b17e024c1d7cbb475279491bc6f92ea 100644 (file)
@@ -59,6 +59,7 @@ use OCP\ITempManager;
 use OCP\IURLGenerator;
 use OCP\Lock\ILockingProvider;
 use OCP\Notification\IManager;
+use OCP\Security\Bruteforce\IThrottler;
 use PHPUnit\Framework\MockObject\MockObject;
 use Psr\Http\Message\ResponseInterface;
 use Psr\Log\LoggerInterface;
@@ -148,6 +149,7 @@ class CheckSetupControllerTest extends TestCase {
                $this->logger = $this->getMockBuilder(LoggerInterface::class)->getMock();
                $this->db = $this->getMockBuilder(Connection::class)
                        ->disableOriginalConstructor()->getMock();
+               $this->throttler = $this->createMock(IThrottler::class);
                $this->lockingProvider = $this->getMockBuilder(ILockingProvider::class)->getMock();
                $this->dateTimeFormatter = $this->getMockBuilder(IDateTimeFormatter::class)->getMock();
                $this->memoryInfo = $this->getMockBuilder(MemoryInfo::class)
@@ -180,6 +182,7 @@ class CheckSetupControllerTest extends TestCase {
                                $this->secureRandom,
                                $this->iniGetWrapper,
                                $this->connection,
+                               $this->throttler,
                                $this->tempManager,
                                $this->notificationManager,
                                $this->appManager,
@@ -665,6 +668,8 @@ class CheckSetupControllerTest extends TestCase {
                                'isFairUseOfFreePushService' => false,
                                'temporaryDirectoryWritable' => false,
                                \OCA\Settings\SetupChecks\LdapInvalidUuids::class => ['pass' => true, 'description' => 'Invalid UUIDs of LDAP users or groups have been found. Please review your "Override UUID detection" settings in the Expert part of the LDAP configuration and use "occ ldap:update-uuid" to update them.', 'severity' => 'warning'],
+                               'isBruteforceThrottled' => false,
+                               'bruteforceRemoteAddress' => '',
                        ]
                );
                $this->assertEquals($expected, $this->checkSetupController->check());
@@ -690,6 +695,7 @@ class CheckSetupControllerTest extends TestCase {
                                $this->secureRandom,
                                $this->iniGetWrapper,
                                $this->connection,
+                               $this->throttler,
                                $this->tempManager,
                                $this->notificationManager,
                                $this->appManager,
@@ -1455,6 +1461,7 @@ Array
                        $this->secureRandom,
                        $this->iniGetWrapper,
                        $this->connection,
+                       $this->throttler,
                        $this->tempManager,
                        $this->notificationManager,
                        $this->appManager,
@@ -1510,6 +1517,7 @@ Array
                        $this->secureRandom,
                        $this->iniGetWrapper,
                        $this->connection,
+                       $this->throttler,
                        $this->tempManager,
                        $this->notificationManager,
                        $this->appManager,
index 4fb020e44a311d66424fe03c5f9e34691a7b563f..c3e892de2945d7982b8a97b5e46c60a85a560eef 100644 (file)
                                                        type: OC.SetupChecks.MESSAGE_TYPE_INFO
                                                });
                                        }
+                                       if (data.isBruteforceThrottled) {
+                                               messages.push({
+                                                       msg: t('core', 'Your remote address was identified as "{remoteAddress}" and is bruteforce throttled at the moment slowing down the performance of various requests. If the remote address is not your address this can be an indication that a proxy is not configured correctly. Further information can be found in the {linkstart}documentation ↗{linkend}.', { remoteAddress: data.bruteforceRemoteAddress })
+                                                               .replace('{linkstart}', '<a target="_blank" rel="noreferrer noopener" class="external" href="' + data.reverseProxyDocs + '">')
+                                                               .replace('{linkend}', '</a>'),
+                                                       type: OC.SetupChecks.MESSAGE_TYPE_ERROR
+                                               });
+                                       }
                                        if(!data.hasWorkingFileLocking) {
                                                messages.push({
                                                        msg: t('core', 'Transactional file locking is disabled, this might lead to issues with race conditions. Enable "filelocking.enabled" in config.php to avoid these problems. See the {linkstart}documentation ↗{linkend} for more information.')
index 43f42d2610e664da482d512c14a0e86053fb0011..163a21c46a786fe9996593f534900eb59c77c9b1 100644 (file)
@@ -814,6 +814,67 @@ describe('OC.SetupChecks tests', function() {
                        });
                });
 
+               it('should return an error if the admin IP is bruteforce throttled', function(done) {
+                       var async = OC.SetupChecks.checkSetup();
+
+                       suite.server.requests[0].respond(
+                               200,
+                               {
+                                       'Content-Type': 'application/json',
+                               },
+                               JSON.stringify({
+                                       hasFileinfoInstalled: true,
+                                       isGetenvServerWorking: true,
+                                       isReadOnlyConfig: false,
+                                       wasEmailTestSuccessful: true,
+                                       hasWorkingFileLocking: true,
+                                       hasDBFileLocking: false,
+                                       hasValidTransactionIsolationLevel: true,
+                                       suggestedOverwriteCliURL: '',
+                                       isRandomnessSecure: true,
+                                       isFairUseOfFreePushService: true,
+                                       isBruteforceThrottled: true,
+                                       bruteforceRemoteAddress: '::1',
+                                       serverHasInternetConnectionProblems: false,
+                                       isMemcacheConfigured: true,
+                                       forwardedForHeadersWorking: true,
+                                       reverseProxyDocs: 'https://docs.nextcloud.com/foo/bar.html',
+                                       isCorrectMemcachedPHPModuleInstalled: true,
+                                       hasPassedCodeIntegrityCheck: true,
+                                       OpcacheSetupRecommendations: [],
+                                       isSettimelimitAvailable: true,
+                                       hasFreeTypeSupport: true,
+                                       missingIndexes: [],
+                                       missingPrimaryKeys: [],
+                                       missingColumns: [],
+                                       cronErrors: [],
+                                       cronInfo: {
+                                               diffInSeconds: 0
+                                       },
+                                       isMemoryLimitSufficient: true,
+                                       appDirsWithDifferentOwner: [],
+                                       isImagickEnabled: true,
+                                       areWebauthnExtensionsEnabled: true,
+                                       is64bit: true,
+                                       recommendedPHPModules: [],
+                                       pendingBigIntConversionColumns: [],
+                                       isMysqlUsedWithoutUTF8MB4: false,
+                                       isDefaultPhoneRegionSet: true,
+                                       isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed: true,
+                                       reverseProxyGeneratedURL: 'https://server',
+                                       temporaryDirectoryWritable: true,
+                               })
+                       );
+
+                       async.done(function( data, s, x ){
+                               expect(data).toEqual([{
+                                       msg: 'Your remote address was identified as "::1" and is bruteforce throttled at the moment slowing down the performance of various requests. If the remote address is not your address this can be an indication that a proxy is not configured correctly. Further information can be found in the <a target="_blank" rel="noreferrer noopener" class="external" href="https://docs.nextcloud.com/foo/bar.html">documentation ↗</a>.',
+                                       type: OC.SetupChecks.MESSAGE_TYPE_ERROR
+                               }]);
+                               done();
+                       });
+               });
+
                it('should return an error if set_time_limit is unavailable', function(done) {
                        var async = OC.SetupChecks.checkSetup();