Browse Source

Add bruteforce protection to changePersonalPassword

While the risk is actually quite low because one would already have the user session and could potentially do other havoc it makes sense to throttle here in case of invalid previous password attempts.

Signed-off-by: Lukas Reschke <lukas@statuscode.ch>
tags/v12.0.0beta1
Lukas Reschke 7 years ago
parent
commit
805419bb95
No account linked to committer's email address

+ 4
- 1
settings/Controller/ChangePasswordController.php View File

/** /**
* @NoAdminRequired * @NoAdminRequired
* @NoSubadminRequired * @NoSubadminRequired
* @BruteForceProtection(action=changePersonalPassword)
* *
* @param string $oldpassword * @param string $oldpassword
* @param string $newpassword * @param string $newpassword
/** @var IUser $user */ /** @var IUser $user */
$user = $this->userManager->checkPassword($this->userId, $oldpassword); $user = $this->userManager->checkPassword($this->userId, $oldpassword);
if ($user === false) { if ($user === false) {
return new JSONResponse([
$response = new JSONResponse([
'status' => 'error', 'status' => 'error',
'data' => [ 'data' => [
'message' => $this->l->t('Wrong password'), 'message' => $this->l->t('Wrong password'),
], ],
]); ]);
$response->throttle();
return $response;
} }


try { try {

+ 31
- 39
tests/Core/Controller/ChangePasswordControllerTest.php View File

use OC\Settings\Controller\ChangePasswordController; use OC\Settings\Controller\ChangePasswordController;
use OC\User\Session; use OC\User\Session;
use OCP\App\IAppManager; use OCP\App\IAppManager;
use OCP\AppFramework\Http\JSONResponse;
use OCP\IGroupManager; use OCP\IGroupManager;
use OCP\IL10N; use OCP\IL10N;
use OCP\IRequest;
use OCP\IUserManager; use OCP\IUserManager;


class ChangePasswordControllerTest extends \Test\TestCase { class ChangePasswordControllerTest extends \Test\TestCase {

/** @var string */ /** @var string */
private $userId = 'currentUser'; private $userId = 'currentUser';

/** @var IUserManager */
/** @var IUserManager|\PHPUnit_Framework_MockObject_MockObject */
private $userManager; private $userManager;

/** @var Session */
/** @var Session|\PHPUnit_Framework_MockObject_MockObject */
private $userSession; private $userSession;

/** @var IGroupManager */
/** @var IGroupManager|\PHPUnit_Framework_MockObject_MockObject */
private $groupManager; private $groupManager;

/** @var IAppManager */
/** @var IAppManager|\PHPUnit_Framework_MockObject_MockObject */
private $appManager; private $appManager;

/** @var IL10N */
/** @var IL10N|\PHPUnit_Framework_MockObject_MockObject */
private $l; private $l;

/** @var ChangePasswordController */ /** @var ChangePasswordController */
private $controller; private $controller;


public function setUp() { public function setUp() {
parent::setUp(); parent::setUp();


$this->userManager = $this->getMockBuilder('OCP\IUserManager')->getMock();
$this->userSession = $this->getMockBuilder('OC\User\Session')->disableOriginalConstructor()->getMock();
$this->groupManager = $this->getMockBuilder('OCP\IGroupManager')->getMock();
$this->appManager = $this->getMockBuilder('OCP\App\IAppManager')->getMock();
$this->l = $this->getMockBuilder('OCP\IL10N')->getMock();

$this->userManager = $this->createMock(IUserManager::class);
$this->userSession = $this->createMock(Session::class);
$this->groupManager = $this->createMock(IGroupManager::class);
$this->appManager = $this->createMock(IAppManager::class);
$this->l = $this->createMock(IL10N::class);
$this->l->method('t')->will($this->returnArgument(0)); $this->l->method('t')->will($this->returnArgument(0));


$request = $this->getMockBuilder('OCP\IRequest')->getMock();
/** @var IRequest|\PHPUnit_Framework_MockObject_MockObject $request */
$request = $this->createMock(IRequest::class);


$this->controller = new ChangePasswordController( $this->controller = new ChangePasswordController(
'core', 'core',
->with($this->userId, 'old') ->with($this->userId, 'old')
->willReturn(false); ->willReturn(false);


$expects = [
$expects = new JSONResponse([
'status' => 'error', 'status' => 'error',
'data' => [ 'data' => [
'message' => 'Wrong password', 'message' => 'Wrong password',
], ],
];

$res = $this->controller->changePersonalPassword('old', 'new');
]);
$expects->throttle();


$this->assertEquals($expects, $res->getData());
$actual = $this->controller->changePersonalPassword('old', 'new');
$this->assertEquals($expects, $actual);
} }


public function testChangePersonalPasswordCommonPassword() { public function testChangePersonalPasswordCommonPassword() {
->with('new') ->with('new')
->will($this->throwException(new HintException('Common password'))); ->will($this->throwException(new HintException('Common password')));


$expects = [
$expects = new JSONResponse([
'status' => 'error', 'status' => 'error',
'data' => [ 'data' => [
'message' => 'Common password', 'message' => 'Common password',
], ],
];

$res = $this->controller->changePersonalPassword('old', 'new');
]);


$this->assertEquals($expects, $res->getData());
$actual = $this->controller->changePersonalPassword('old', 'new');
$this->assertEquals($expects, $actual);
} }


public function testChangePersonalPasswordNoNewPassword() { public function testChangePersonalPasswordNoNewPassword() {
->with('new') ->with('new')
->willReturn(false); ->willReturn(false);


$expects = [
$expects = new JSONResponse([
'status' => 'error', 'status' => 'error',
];
]);


$res = $this->controller->changePersonalPassword('old', 'new');

$this->assertEquals($expects, $res->getData());
$actual = $this->controller->changePersonalPassword('old', 'new');
$this->assertEquals($expects, $actual);
} }


public function testChangePersonalPassword() { public function testChangePersonalPassword() {
->method('updateSessionTokenPassword') ->method('updateSessionTokenPassword')
->with('new'); ->with('new');


$expects = [
$expects = new JSONResponse([
'status' => 'success', 'status' => 'success',
'data' => [ 'data' => [
'message' => 'Saved', 'message' => 'Saved',
], ],
];

$res = $this->controller->changePersonalPassword('old', 'new');
]);


$this->assertEquals($expects, $res->getData());
$actual = $this->controller->changePersonalPassword('old', 'new');
$this->assertEquals($expects, $actual);
} }
} }

Loading…
Cancel
Save