summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoeland Jago Douma <roeland@famdouma.nl>2018-10-29 22:12:18 +0100
committerRoeland Jago Douma <roeland@famdouma.nl>2018-11-02 10:54:50 +0100
commit6971ecef9d5223e9996c14abb93458c33daa5989 (patch)
tree70acb4974f7ef41ea53a43c069c16686381b4416
parent661062271f35a5cadca91e5a42885e726f104eef (diff)
downloadnextcloud-server-6971ecef9d5223e9996c14abb93458c33daa5989.tar.gz
nextcloud-server-6971ecef9d5223e9996c14abb93458c33daa5989.zip
Reset bruteforce on token refresh OAuth
When using atoken obtained via OAuth the token expires. Resulting in brute force attempts hitting the requesting IP. This resets the brute force attempts for that UID on a valid refresh of the token. Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>
-rw-r--r--apps/oauth2/lib/Controller/OauthApiController.php10
-rw-r--r--apps/oauth2/tests/Controller/OauthApiControllerTest.php40
-rw-r--r--lib/private/Server.php3
3 files changed, 50 insertions, 3 deletions
diff --git a/apps/oauth2/lib/Controller/OauthApiController.php b/apps/oauth2/lib/Controller/OauthApiController.php
index 2083741fa0c..978ca76d75b 100644
--- a/apps/oauth2/lib/Controller/OauthApiController.php
+++ b/apps/oauth2/lib/Controller/OauthApiController.php
@@ -24,6 +24,7 @@ namespace OCA\OAuth2\Controller;
use OC\Authentication\Exceptions\InvalidTokenException;
use OC\Authentication\Token\ExpiredTokenException;
use OC\Authentication\Token\IProvider as TokenProvider;
+use OC\Security\Bruteforce\Throttler;
use OCA\OAuth2\Db\AccessTokenMapper;
use OCA\OAuth2\Db\ClientMapper;
use OCA\OAuth2\Exceptions\AccessTokenNotFoundException;
@@ -49,6 +50,8 @@ class OauthApiController extends Controller {
private $secureRandom;
/** @var ITimeFactory */
private $time;
+ /** @var Throttler */
+ private $throttler;
/**
* @param string $appName
@@ -59,6 +62,7 @@ class OauthApiController extends Controller {
* @param TokenProvider $tokenProvider
* @param ISecureRandom $secureRandom
* @param ITimeFactory $time
+ * @param Throttler $throttler
*/
public function __construct($appName,
IRequest $request,
@@ -67,7 +71,8 @@ class OauthApiController extends Controller {
ClientMapper $clientMapper,
TokenProvider $tokenProvider,
ISecureRandom $secureRandom,
- ITimeFactory $time) {
+ ITimeFactory $time,
+ Throttler $throttler) {
parent::__construct($appName, $request);
$this->crypto = $crypto;
$this->accessTokenMapper = $accessTokenMapper;
@@ -75,6 +80,7 @@ class OauthApiController extends Controller {
$this->tokenProvider = $tokenProvider;
$this->secureRandom = $secureRandom;
$this->time = $time;
+ $this->throttler = $throttler;
}
/**
@@ -164,6 +170,8 @@ class OauthApiController extends Controller {
$accessToken->setEncryptedToken($this->crypto->encrypt($newToken, $newCode));
$this->accessTokenMapper->update($accessToken);
+ $this->throttler->resetDelay($this->request->getRemoteAddress(), 'login', ['user' => $appToken->getUID()]);
+
return new JSONResponse(
[
'access_token' => $newToken,
diff --git a/apps/oauth2/tests/Controller/OauthApiControllerTest.php b/apps/oauth2/tests/Controller/OauthApiControllerTest.php
index 10748485971..7d5dc9be258 100644
--- a/apps/oauth2/tests/Controller/OauthApiControllerTest.php
+++ b/apps/oauth2/tests/Controller/OauthApiControllerTest.php
@@ -27,6 +27,7 @@ use OC\Authentication\Token\DefaultTokenMapper;
use OC\Authentication\Token\ExpiredTokenException;
use OC\Authentication\Token\IProvider as TokenProvider;
use OC\Authentication\Token\IToken;
+use OC\Security\Bruteforce\Throttler;
use OCA\OAuth2\Controller\OauthApiController;
use OCA\OAuth2\Db\AccessToken;
use OCA\OAuth2\Db\AccessTokenMapper;
@@ -57,6 +58,8 @@ class OauthApiControllerTest extends TestCase {
private $secureRandom;
/** @var ITimeFactory|\PHPUnit_Framework_MockObject_MockObject */
private $time;
+ /** @var Throttler|\PHPUnit_Framework_MockObject_MockObject */
+ private $throttler;
/** @var OauthApiController */
private $oauthApiController;
@@ -70,6 +73,7 @@ class OauthApiControllerTest extends TestCase {
$this->tokenProvider = $this->createMock(TokenProvider::class);
$this->secureRandom = $this->createMock(ISecureRandom::class);
$this->time = $this->createMock(ITimeFactory::class);
+ $this->throttler = $this->createMock(Throttler::class);
$this->oauthApiController = new OauthApiController(
'oauth2',
@@ -79,7 +83,8 @@ class OauthApiControllerTest extends TestCase {
$this->clientMapper,
$this->tokenProvider,
$this->secureRandom,
- $this->time
+ $this->time,
+ $this->throttler
);
}
@@ -286,6 +291,17 @@ class OauthApiControllerTest extends TestCase {
'user_id' => 'userId',
]);
+ $this->request->method('getRemoteAddress')
+ ->willReturn('1.2.3.4');
+
+ $this->throttler->expects($this->once())
+ ->method('resetDelay')
+ ->with(
+ '1.2.3.4',
+ 'login',
+ ['user' => 'userId']
+ );
+
$this->assertEquals($expected, $this->oauthApiController->getToken('refresh_token', null, 'validrefresh', 'clientId', 'clientSecret'));
}
@@ -370,6 +386,17 @@ class OauthApiControllerTest extends TestCase {
$this->request->server['PHP_AUTH_USER'] = 'clientId';
$this->request->server['PHP_AUTH_PW'] = 'clientSecret';
+ $this->request->method('getRemoteAddress')
+ ->willReturn('1.2.3.4');
+
+ $this->throttler->expects($this->once())
+ ->method('resetDelay')
+ ->with(
+ '1.2.3.4',
+ 'login',
+ ['user' => 'userId']
+ );
+
$this->assertEquals($expected, $this->oauthApiController->getToken('refresh_token', null, 'validrefresh', null, null));
}
@@ -451,6 +478,17 @@ class OauthApiControllerTest extends TestCase {
'user_id' => 'userId',
]);
+ $this->request->method('getRemoteAddress')
+ ->willReturn('1.2.3.4');
+
+ $this->throttler->expects($this->once())
+ ->method('resetDelay')
+ ->with(
+ '1.2.3.4',
+ 'login',
+ ['user' => 'userId']
+ );
+
$this->assertEquals($expected, $this->oauthApiController->getToken('refresh_token', null, 'validrefresh', 'clientId', 'clientSecret'));
}
}
diff --git a/lib/private/Server.php b/lib/private/Server.php
index 84af87f0d2f..f66f780ad52 100644
--- a/lib/private/Server.php
+++ b/lib/private/Server.php
@@ -758,7 +758,7 @@ class Server extends ServerContainer implements IServerContainer {
$this->registerService('TrustedDomainHelper', function ($c) {
return new TrustedDomainHelper($this->getConfig());
});
- $this->registerService('Throttler', function (Server $c) {
+ $this->registerService(Throttler::class, function (Server $c) {
return new Throttler(
$c->getDatabaseConnection(),
new TimeFactory(),
@@ -766,6 +766,7 @@ class Server extends ServerContainer implements IServerContainer {
$c->getConfig()
);
});
+ $this->registerAlias('Throttler', Throttler::class);
$this->registerService('IntegrityCodeChecker', function (Server $c) {
// IConfig and IAppManager requires a working database. This code
// might however be called when ownCloud is not yet setup.