Skip to content

Commit

Permalink
Improve brute force protection checks (#20543) (#20579)
Browse files Browse the repository at this point in the history
  • Loading branch information
sgiehl authored Apr 14, 2023
1 parent 3a9e718 commit 803382f
Showing 1 changed file with 16 additions and 21 deletions.
37 changes: 16 additions & 21 deletions plugins/Login/Login.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,18 @@ public function registerEvents()
'API.UsersManager.createAppSpecificTokenAuth' => 'beforeLoginCheckBruteForce', // doesn't require auth but can be used to authenticate

// for brute force prevention of all UI requests
'Controller.Login.logme' => 'beforeLoginCheckBruteForceForUserPwdLogin',
'Controller.Login.' => 'beforeLoginCheckBruteForceForUserPwdLogin',
'Controller.Login.index' => 'beforeLoginCheckBruteForceForUserPwdLogin',
'Controller.Login.confirmResetPassword' => 'beforeLoginCheckBruteForceForUserPwdLogin',
'Controller.Login.confirmPassword' => 'beforeLoginCheckBruteForceForUserPwdLogin',
'Controller.Login.resetPassword' => 'beforeLoginCheckBruteForceForUserPwdLogin',
'Controller.Login.login' => 'beforeLoginCheckBruteForceForUserPwdLogin',
'Controller.Login.logme' => 'beforeLoginCheckBruteForce',
'Controller.Login.' => 'beforeLoginCheckBruteForce',
'Controller.Login.index' => 'beforeLoginCheckBruteForce',
'Controller.Login.confirmResetPassword' => 'beforeLoginCheckBruteForce',
'Controller.Login.confirmPassword' => 'beforeLoginCheckBruteForce',
'Controller.Login.resetPassword' => 'beforeLoginCheckBruteForce',
'Controller.Login.login' => 'beforeLoginCheckBruteForce',
'Controller.TwoFactorAuth.loginTwoFactorAuth' => 'beforeLoginCheckBruteForce',
'Controller.Login.acceptInvitation' => 'beforeLoginCheckBruteForce',
'Controller.Login.declineInvitation' => 'beforeLoginCheckBruteForce',
'Login.authenticate.successful' => 'beforeLoginCheckBruteForce',
'Login.beforeLoginCheckAllowed' => 'beforeLoginCheckBruteForceForUserPwdLogin', // record any failed attempt in UI
'Login.beforeLoginCheckAllowed' => 'beforeLoginCheckBruteForce',
'Login.recordFailedLoginAttempt' => 'onFailedLoginRecordAttempt', // record any failed attempt in UI
'Login.authenticate.failed' => 'onFailedLoginRecordAttempt', // record any failed attempt in UI
'API.Request.authenticate.failed' => 'onFailedLoginRecordAttempt', // record any failed attempt in Reporting API
Expand All @@ -68,13 +68,13 @@ public function registerEvents()
$loginPlugin = Piwik::getLoginPluginName();

if ($loginPlugin && $loginPlugin !== 'Login') {
$hooks['Controller.'.$loginPlugin.'.logme'] = 'beforeLoginCheckBruteForceForUserPwdLogin';
$hooks['Controller.'.$loginPlugin. '.'] = 'beforeLoginCheckBruteForceForUserPwdLogin';
$hooks['Controller.'.$loginPlugin.'.index'] = 'beforeLoginCheckBruteForceForUserPwdLogin';
$hooks['Controller.'.$loginPlugin.'.confirmResetPassword'] = 'beforeLoginCheckBruteForceForUserPwdLogin';
$hooks['Controller.'.$loginPlugin.'.confirmPassword'] = 'beforeLoginCheckBruteForceForUserPwdLogin';
$hooks['Controller.'.$loginPlugin.'.resetPassword'] = 'beforeLoginCheckBruteForceForUserPwdLogin';
$hooks['Controller.'.$loginPlugin.'.login'] = 'beforeLoginCheckBruteForceForUserPwdLogin';
$hooks['Controller.'.$loginPlugin.'.logme'] = 'beforeLoginCheckBruteForce';
$hooks['Controller.'.$loginPlugin. '.'] = 'beforeLoginCheckBruteForce';
$hooks['Controller.'.$loginPlugin.'.index'] = 'beforeLoginCheckBruteForce';
$hooks['Controller.'.$loginPlugin.'.confirmResetPassword'] = 'beforeLoginCheckBruteForce';
$hooks['Controller.'.$loginPlugin.'.confirmPassword'] = 'beforeLoginCheckBruteForce';
$hooks['Controller.'.$loginPlugin.'.resetPassword'] = 'beforeLoginCheckBruteForce';
$hooks['Controller.'.$loginPlugin.'.login'] = 'beforeLoginCheckBruteForce';
}

return $hooks;
Expand Down Expand Up @@ -123,14 +123,9 @@ public function beforeLoginCheckBruteForce()
if (!$this->hasPerformedBruteForceCheck && $bruteForce->isEnabled() && !$bruteForce->isAllowedToLogin(IP::getIpFromHeader())) {
throw new Exception(Piwik::translate('Login_LoginNotAllowedBecauseBlocked'));
}

// for performance reasons we make sure to execute it only once per request
$this->hasPerformedBruteForceCheck = true;
}

public function beforeLoginCheckBruteForceForUserPwdLogin()
{
// check that IP is not blocked
$this->beforeLoginCheckBruteForce();

// now check that user login (from any ip) is not blocked
$login = $this->getUsernameUsedInPasswordLogin();
Expand Down

0 comments on commit 803382f

Please sign in to comment.