From 87d4c28b4aaacf0078ee78ca27688023cf8b9995 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Mon, 28 Aug 2017 14:24:48 -0600 Subject: [PATCH] Added rate limiting for login and forgot password --- CHANGELOG.md | 1 + classes/admin.php | 16 ++++++++++++---- classes/admincontroller.php | 11 +++++++++++ 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2beb0fea..277da8ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ 1. [](#new) * Added 2-Factor Authentication support to the admin!! + * Added rate-limiting for "failed login attempts" and "forgot password" 1. [](#improved) * Revamped the toggle switch CSS so it's more flexible and works better [#1198](https://github.com/getgrav/grav-plugin-admin/issues/1198) * Improved toggle/button alignment on Page edit view diff --git a/classes/admin.php b/classes/admin.php index f65c3f9d..073669f4 100644 --- a/classes/admin.php +++ b/classes/admin.php @@ -350,6 +350,17 @@ class Admin */ public function authenticate($data, $post) { + $count = $this->grav['config']->get('plugins.login.max_login_count', 5); + $interval = $this->grav['config']->get('plugins.login.max_login_interval', 10); + $login = $this->grav['login']; + + if ($login->isUserRateLimited($this->user, 'login_attempts', $count, $interval)) { + $this->setMessage($this->translate(['PLUGIN_LOGIN.TOO_MANY_LOGIN_ATTEMPTS', $interval]), 'error'); + $this->grav->redirect($post['redirect']); + return true; + } + + if (!$this->user->authenticated && isset($data['username']) && isset($data['password'])) { // Perform RegEX check on submitted username to check for emails if (filter_var($data['username'], FILTER_VALIDATE_EMAIL)) { @@ -385,12 +396,9 @@ class Admin } $user->authenticated = true; - + $this->login->resetRateLimits($user,'login_attempts'); if ($user->authorize('admin.login')) { - - - $this->user = $this->session->user = $user; /** @var Grav $grav */ diff --git a/classes/admincontroller.php b/classes/admincontroller.php index c0f9643b..7c37be22 100644 --- a/classes/admincontroller.php +++ b/classes/admincontroller.php @@ -1152,6 +1152,7 @@ class AdminController extends AdminBaseController $param_sep = $this->grav['config']->get('system.param_sep', ':'); $post = $this->post; $data = $this->data; + $login = $this->grav['login']; $username = isset($data['username']) ? strip_tags(strtolower($data['username'])) : ''; $user = !empty($username) ? User::load($username) : null; @@ -1179,6 +1180,16 @@ class AdminController extends AdminBaseController return true; } + $count = $this->grav['config']->get('plugins.login.max_pw_resets_count', 0); + $interval =$this->grav['config']->get('plugins.login.max_pw_resets_interval', 2); + + if ($login->isUserRateLimited($user, 'pw_resets', $count, $interval)) { + $this->admin->setMessage($this->admin->translate(['PLUGIN_LOGIN.FORGOT_CANNOT_RESET_IT_IS_BLOCKED', $user->email, $interval]), 'error'); + $this->setRedirect($post['redirect']); + + return true; + } + $token = md5(uniqid(mt_rand(), true)); $expire = time() + 604800; // next week