Browse Source

Do not leak the login name - fixes #25047

tags/v9.1.0RC1
Thomas Müller 8 years ago
parent
commit
232d735893
No account linked to committer's email address

+ 3
- 2
core/Controller/LoginController.php View File

* @return RedirectResponse * @return RedirectResponse
*/ */
public function tryLogin($user, $password, $redirect_url) { public function tryLogin($user, $password, $redirect_url) {
$originalUser = $user;
// TODO: Add all the insane error handling // TODO: Add all the insane error handling
/* @var $loginResult IUser */ /* @var $loginResult IUser */
$loginResult = $this->userManager->checkPassword($user, $password); $loginResult = $this->userManager->checkPassword($user, $password);
$this->session->set('loginMessages', [ $this->session->set('loginMessages', [
['invalidpassword'] ['invalidpassword']
]); ]);
// Read current user and append if possible
$args = !is_null($user) ? ['user' => $user] : [];
// Read current user and append if possible - we need to return the unmodified user otherwise we will leak the login name
$args = !is_null($user) ? ['user' => $originalUser] : [];
return new RedirectResponse($this->urlGenerator->linkToRoute('core.login.showLoginForm', $args)); return new RedirectResponse($this->urlGenerator->linkToRoute('core.login.showLoginForm', $args));
} }
// TODO: remove password checks from above and let the user session handle failures // TODO: remove password checks from above and let the user session handle failures

+ 40
- 8
tests/Core/Controller/LoginControllerTest.php View File

use OCP\IRequest; use OCP\IRequest;
use OCP\ISession; use OCP\ISession;
use OCP\IURLGenerator; use OCP\IURLGenerator;
use OCP\IUser;
use OCP\IUserManager; use OCP\IUserManager;
use OCP\IUserSession; use OCP\IUserSession;
use Test\TestCase; use Test\TestCase;
class LoginControllerTest extends TestCase { class LoginControllerTest extends TestCase {
/** @var LoginController */ /** @var LoginController */
private $loginController; private $loginController;
/** @var IRequest */
/** @var IRequest | \PHPUnit_Framework_MockObject_MockObject */
private $request; private $request;
/** @var IUserManager */
/** @var IUserManager | \PHPUnit_Framework_MockObject_MockObject */
private $userManager; private $userManager;
/** @var IConfig */
/** @var IConfig | \PHPUnit_Framework_MockObject_MockObject */
private $config; private $config;
/** @var ISession */
/** @var ISession | \PHPUnit_Framework_MockObject_MockObject */
private $session; private $session;
/** @var IUserSession */
/** @var IUserSession | \PHPUnit_Framework_MockObject_MockObject */
private $userSession; private $userSession;
/** @var IURLGenerator */
/** @var IURLGenerator | \PHPUnit_Framework_MockObject_MockObject */
private $urlGenerator; private $urlGenerator;
/** @var Manager */
/** @var Manager | \PHPUnit_Framework_MockObject_MockObject */
private $twoFactorManager; private $twoFactorManager;


public function setUp() { public function setUp() {
} }


public function testLoginWithValidCredentials() { public function testLoginWithValidCredentials() {
/** @var IUser | \PHPUnit_Framework_MockObject_MockObject $user */
$user = $this->getMock('\OCP\IUser'); $user = $this->getMock('\OCP\IUser');
$password = 'secret'; $password = 'secret';
$indexPageUrl = 'some url'; $indexPageUrl = 'some url';
} }


public function testLoginWithValidCredentialsAndRedirectUrl() { public function testLoginWithValidCredentialsAndRedirectUrl() {
/** @var IUser | \PHPUnit_Framework_MockObject_MockObject $user */
$user = $this->getMock('\OCP\IUser'); $user = $this->getMock('\OCP\IUser');
$user->expects($this->any()) $user->expects($this->any())
->method('getUID') ->method('getUID')
} }
public function testLoginWithTwoFactorEnforced() { public function testLoginWithTwoFactorEnforced() {
/** @var IUser | \PHPUnit_Framework_MockObject_MockObject $user */
$user = $this->getMock('\OCP\IUser'); $user = $this->getMock('\OCP\IUser');
$user->expects($this->any()) $user->expects($this->any())
->method('getUID') ->method('getUID')
->with('core.TwoFactorChallenge.selectChallenge') ->with('core.TwoFactorChallenge.selectChallenge')
->will($this->returnValue($challengeUrl)); ->will($this->returnValue($challengeUrl));


$expected = new \OCP\AppFramework\Http\RedirectResponse($challengeUrl);
$expected = new RedirectResponse($challengeUrl);
$this->assertEquals($expected, $this->loginController->tryLogin('john@doe.com', $password, null)); $this->assertEquals($expected, $this->loginController->tryLogin('john@doe.com', $password, null));
} }


public function testToNotLeakLoginName() {
/** @var IUser | \PHPUnit_Framework_MockObject_MockObject $user */
$user = $this->getMock('\OCP\IUser');
$user->expects($this->any())
->method('getUID')
->will($this->returnValue('john'));

$this->userManager->expects($this->exactly(2))
->method('checkPassword')
->withConsecutive(
['john@doe.com', 'just wrong'],
['john', 'just wrong']
)
->willReturn(false);
$this->userManager->expects($this->once())
->method('getByEmail')
->with('john@doe.com')
->willReturn([$user]);

$this->urlGenerator->expects($this->once())
->method('linkToRoute')
->with('core.login.showLoginForm', ['user' => 'john@doe.com'])
->will($this->returnValue(''));

$expected = new RedirectResponse('');
$this->assertEquals($expected, $this->loginController->tryLogin('john@doe.com', 'just wrong', null));
}
} }

Loading…
Cancel
Save