diff --git a/apps/settings/lib/Controller/CheckSetupController.php b/apps/settings/lib/Controller/CheckSetupController.php
index 0353862bab0ba..80be57268b07c 100644
--- a/apps/settings/lib/Controller/CheckSetupController.php
+++ b/apps/settings/lib/Controller/CheckSetupController.php
@@ -90,6 +90,7 @@
use OCP\IURLGenerator;
use OCP\Lock\ILockingProvider;
use OCP\Notification\IManager;
+use OCP\Security\Bruteforce\IThrottler;
use OCP\Security\ISecureRandom;
use Psr\Log\LoggerInterface;
@@ -123,6 +124,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 @@ public function __construct($AppName,
ISecureRandom $secureRandom,
IniGetWrapper $iniGetWrapper,
IDBConnection $connection,
+ IThrottler $throttler,
ITempManager $tempManager,
IManager $manager,
IAppManager $appManager,
@@ -162,6 +166,7 @@ public function __construct($AppName,
$this->logger = $logger;
$this->dispatcher = $dispatcher;
$this->db = $db;
+ $this->throttler = $throttler;
$this->lockingProvider = $lockingProvider;
$this->dateTimeFormatter = $dateTimeFormatter;
$this->memoryInfo = $memoryInfo;
@@ -920,6 +925,8 @@ public function check() {
'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'),
diff --git a/apps/settings/tests/Controller/CheckSetupControllerTest.php b/apps/settings/tests/Controller/CheckSetupControllerTest.php
index 564c1cbb62d0c..d4af6bd603cd8 100644
--- a/apps/settings/tests/Controller/CheckSetupControllerTest.php
+++ b/apps/settings/tests/Controller/CheckSetupControllerTest.php
@@ -59,6 +59,7 @@
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;
@@ -143,6 +144,7 @@ protected function setUp(): void {
$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)
@@ -174,6 +176,7 @@ protected function setUp(): void {
$this->secureRandom,
$this->iniGetWrapper,
$this->connection,
+ $this->throttler,
$this->tempManager,
$this->notificationManager,
$this->appManager,
@@ -659,6 +662,8 @@ public function testCheck() {
'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());
@@ -683,6 +688,7 @@ public function testGetCurlVersion() {
$this->secureRandom,
$this->iniGetWrapper,
$this->connection,
+ $this->throttler,
$this->tempManager,
$this->notificationManager,
$this->appManager,
@@ -1410,6 +1416,7 @@ public function testIsMysqlUsedWithoutUTF8MB4(string $db, bool $useUTF8MB4, bool
$this->secureRandom,
$this->iniGetWrapper,
$this->connection,
+ $this->throttler,
$this->tempManager,
$this->notificationManager,
$this->appManager,
@@ -1464,6 +1471,7 @@ public function testIsEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed(string $m
$this->secureRandom,
$this->iniGetWrapper,
$this->connection,
+ $this->throttler,
$this->tempManager,
$this->notificationManager,
$this->appManager,
diff --git a/core/js/setupchecks.js b/core/js/setupchecks.js
index 4fb020e44a311..c3e892de2945d 100644
--- a/core/js/setupchecks.js
+++ b/core/js/setupchecks.js
@@ -215,6 +215,14 @@
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}', '')
+ .replace('{linkend}', ''),
+ 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.')
diff --git a/core/js/tests/specs/setupchecksSpec.js b/core/js/tests/specs/setupchecksSpec.js
index 43f42d2610e66..163a21c46a786 100644
--- a/core/js/tests/specs/setupchecksSpec.js
+++ b/core/js/tests/specs/setupchecksSpec.js
@@ -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 documentation ↗.',
+ 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();