Skip to content

Commit

Permalink
Merge pull request #38268 from nextcloud/backport/38267/stable26
Browse files Browse the repository at this point in the history
[stable26] fix(lostpassword): Also rate limit the setPassword endpoint
  • Loading branch information
nickvergessen authored May 16, 2023
2 parents f7fdaf8 + 156cc8d commit e05da15
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 13 deletions.
16 changes: 11 additions & 5 deletions core/Controller/LostController.php
Original file line number Diff line number Diff line change
Expand Up @@ -223,16 +223,18 @@ public function email(string $user): JSONResponse {

/**
* @PublicPage
* @BruteForceProtection(action=passwordResetEmail)
* @AnonRateThrottle(limit=10, period=300)
*/
public function setPassword(string $token, string $userId, string $password, bool $proceed): array {
public function setPassword(string $token, string $userId, string $password, bool $proceed): JSONResponse {
if ($this->encryptionManager->isEnabled() && !$proceed) {
$encryptionModules = $this->encryptionManager->getEncryptionModules();
foreach ($encryptionModules as $module) {
/** @var IEncryptionModule $instance */
$instance = call_user_func($module['callback']);
// this way we can find out whether per-user keys are used or a system wide encryption key
if ($instance->needDetailedAccessList()) {
return $this->error('', ['encryption' => true]);
return new JSONResponse($this->error('', ['encryption' => true]));
}
}
}
Expand Down Expand Up @@ -260,12 +262,16 @@ public function setPassword(string $token, string $userId, string $password, boo
$this->config->deleteUserValue($userId, 'core', 'lostpassword');
@\OC::$server->getUserSession()->unsetMagicInCookie();
} catch (HintException $e) {
return $this->error($e->getHint());
$response = new JSONResponse($this->error($e->getHint()));
$response->throttle();
return $response;
} catch (Exception $e) {
return $this->error($e->getMessage());
$response = new JSONResponse($this->error($e->getMessage()));
$response->throttle();
return $response;
}

return $this->success(['user' => $userId]);
return new JSONResponse($this->success(['user' => $userId]));
}

/**
Expand Down
16 changes: 8 additions & 8 deletions tests/Core/Controller/LostControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ public function testSetPasswordUnsuccessful() {

$response = $this->lostController->setPassword('TheOnlyAndOnlyOneTokenToResetThePassword', 'ValidTokenUser', 'NewPassword', true);
$expectedResponse = ['status' => 'error', 'msg' => ''];
$this->assertSame($expectedResponse, $response);
$this->assertSame($expectedResponse, $response->getData());
}

public function testSetPasswordSuccessful() {
Expand Down Expand Up @@ -475,7 +475,7 @@ public function testSetPasswordSuccessful() {

$response = $this->lostController->setPassword('TheOnlyAndOnlyOneTokenToResetThePassword', 'ValidTokenUser', 'NewPassword', true);
$expectedResponse = ['user' => 'ValidTokenUser', 'status' => 'success'];
$this->assertSame($expectedResponse, $response);
$this->assertSame($expectedResponse, $response->getData());
}

public function testSetPasswordExpiredToken() {
Expand All @@ -494,7 +494,7 @@ public function testSetPasswordExpiredToken() {
'status' => 'error',
'msg' => 'Could not reset password because the token is expired',
];
$this->assertSame($expectedResponse, $response);
$this->assertSame($expectedResponse, $response->getData());
}

public function testSetPasswordInvalidDataInDb() {
Expand All @@ -514,7 +514,7 @@ public function testSetPasswordInvalidDataInDb() {
'status' => 'error',
'msg' => 'Could not reset password because the token is invalid',
];
$this->assertSame($expectedResponse, $response);
$this->assertSame($expectedResponse, $response->getData());
}

public function testIsSetPasswordWithoutTokenFailing() {
Expand All @@ -533,7 +533,7 @@ public function testIsSetPasswordWithoutTokenFailing() {
'status' => 'error',
'msg' => 'Could not reset password because the token is invalid'
];
$this->assertSame($expectedResponse, $response);
$this->assertSame($expectedResponse, $response->getData());
}

public function testSetPasswordForDisabledUser() {
Expand Down Expand Up @@ -563,7 +563,7 @@ public function testSetPasswordForDisabledUser() {
'status' => 'error',
'msg' => 'Could not reset password because the token is invalid'
];
$this->assertSame($expectedResponse, $response);
$this->assertSame($expectedResponse, $response->getData());
}

public function testSendEmailNoEmail() {
Expand Down Expand Up @@ -599,7 +599,7 @@ public function testSetPasswordEncryptionDontProceedPerUserKey() {
}]]);
$response = $this->lostController->setPassword('myToken', 'user', 'newpass', false);
$expectedResponse = ['status' => 'error', 'msg' => '', 'encryption' => true];
$this->assertSame($expectedResponse, $response);
$this->assertSame($expectedResponse, $response->getData());
}

public function testSetPasswordDontProceedMasterKey() {
Expand Down Expand Up @@ -627,7 +627,7 @@ public function testSetPasswordDontProceedMasterKey() {

$response = $this->lostController->setPassword('TheOnlyAndOnlyOneTokenToResetThePassword', 'ValidTokenUser', 'NewPassword', false);
$expectedResponse = ['user' => 'ValidTokenUser', 'status' => 'success'];
$this->assertSame($expectedResponse, $response);
$this->assertSame($expectedResponse, $response->getData());
}

public function testTwoUsersWithSameEmail() {
Expand Down

0 comments on commit e05da15

Please sign in to comment.