From f32c893546340c8c279fd1ab6d4269e9d6539bc2 Mon Sep 17 00:00:00 2001 From: Daniel Hensby Date: Mon, 18 Apr 2016 18:35:14 +0100 Subject: [PATCH] [SS-2016-005] FIX Apply brute force protection to default admin --- security/Member.php | 4 ++-- security/MemberAuthenticator.php | 7 +++++-- tests/security/MemberAuthenticatorTest.php | 18 ++++++++++++++++++ 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/security/Member.php b/security/Member.php index c7fe84abd..23c771a3e 100644 --- a/security/Member.php +++ b/security/Member.php @@ -349,7 +349,7 @@ class Member extends DataObject implements TemplateGlobalProvider { * Returns true if this user is locked out */ public function isLockedOut() { - return $this->LockedOutUntil && time() < strtotime($this->LockedOutUntil); + return $this->LockedOutUntil && SS_Datetime::now()->Format('U') < strtotime($this->LockedOutUntil); } /** @@ -1565,7 +1565,7 @@ class Member extends DataObject implements TemplateGlobalProvider { if($this->FailedLoginCount >= self::config()->lock_out_after_incorrect_logins) { $lockoutMins = self::config()->lock_out_delay_mins; - $this->LockedOutUntil = date('Y-m-d H:i:s', time() + $lockoutMins*60); + $this->LockedOutUntil = date('Y-m-d H:i:s', SS_Datetime::now()->Format('U') + $lockoutMins*60); $this->write(); } } diff --git a/security/MemberAuthenticator.php b/security/MemberAuthenticator.php index 4fa72b8cd..6f8a473dd 100644 --- a/security/MemberAuthenticator.php +++ b/security/MemberAuthenticator.php @@ -49,8 +49,11 @@ class MemberAuthenticator extends Authenticator { if($asDefaultAdmin) { // If logging is as default admin, ensure record is setup correctly $member = Member::default_admin(); - $success = Security::check_default_admin($email, $data['Password']); - if($success) return $member; + $success = !$member->isLockedOut() && Security::check_default_admin($email, $data['Password']); + //protect against failed login + if($success) { + return $member; + } } // Attempt to identify user by email diff --git a/tests/security/MemberAuthenticatorTest.php b/tests/security/MemberAuthenticatorTest.php index 1b1f6c17b..3278a6eee 100644 --- a/tests/security/MemberAuthenticatorTest.php +++ b/tests/security/MemberAuthenticatorTest.php @@ -164,4 +164,22 @@ class MemberAuthenticatorTest extends SapphireTest { $this->assertEquals('The provided details don't seem to be correct. Please try again.', $form->Message()); $this->assertEquals('bad', $form->MessageType()); } + + public function testDefaultAdminLockOut() + { + Config::inst()->update('Member', 'lock_out_after_incorrect_logins', 1); + Config::inst()->update('Member', 'lock_out_delay_mins', 10); + SS_Datetime::set_mock_now('2016-04-18 00:00:00'); + $controller = new Security(); + $form = new Form($controller, 'Form', new FieldList(), new FieldList()); + + // Test correct login + MemberAuthenticator::authenticate(array( + 'Email' => 'admin', + 'Password' => 'wrongpassword' + ), $form); + + $this->assertTrue(Member::default_admin()->isLockedOut()); + $this->assertEquals(Member::default_admin()->LockedOutUntil, '2016-04-18 00:10:00'); + } }