diff options
author | Thomas Steur <tsteur@users.noreply.github.com> | 2018-12-10 22:47:02 +0300 |
---|---|---|
committer | diosmosis <diosmosis@users.noreply.github.com> | 2018-12-10 22:47:02 +0300 |
commit | 491ff0d8ecd7d2e9daeeb103a2a7fc099526dff9 (patch) | |
tree | 9a242e11fcda26bc8cace3de4594c916acbe9f1b /plugins/Login/SystemSettings.php | |
parent | 43b61590e51980965c8c9731d79e0b1479e8feb6 (diff) |
Lock down accounts by IP after N failed attemps at logging in (#13472)
* some basic work on preventing brute force attacks
* change order
* delete depending on configured value
* show log and feature to unblock ips etc
* more tweaks
* lots of fixes, improvements, and tests
* add more tests
* add more fixes
* fix typo
* make sure to check for all API requests whether allowed
* apply feedback
* block more usages
* improve usage
* fix some tests
* fix some tests
* fix memory problem
* do not whitelist ips for brute force tests
* trying to fix tests
* only delete if installed
* use query
* fix some tests
* better fix
* fix some tests
* fix ui tests
* fix more tests
Diffstat (limited to 'plugins/Login/SystemSettings.php')
-rw-r--r-- | plugins/Login/SystemSettings.php | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/plugins/Login/SystemSettings.php b/plugins/Login/SystemSettings.php new file mode 100644 index 0000000000..52da3225e4 --- /dev/null +++ b/plugins/Login/SystemSettings.php @@ -0,0 +1,135 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ + +namespace Piwik\Plugins\Login; + +use Piwik\Network\IP; +use Piwik\Piwik; +use Piwik\Settings\Setting; +use Piwik\Settings\FieldConfig; +use Piwik\Validators\IpRanges; + +/** + * Defines Settings for Login. + */ +class SystemSettings extends \Piwik\Settings\Plugin\SystemSettings +{ + /** @var Setting */ + public $enableBruteForceDetection; + + /** @var Setting */ + public $whitelisteBruteForceIps; + + /** @var Setting */ + public $blacklistedBruteForceIps; + + /** @var Setting */ + public $maxFailedLoginsPerMinutes; + + /** @var Setting */ + public $loginAttemptsTimeRange; + + protected function init() + { + $this->enableBruteForceDetection = $this->createEnableBruteForceDetection(); + $this->maxFailedLoginsPerMinutes = $this->createMaxFailedLoginsPerMinutes(); + $this->loginAttemptsTimeRange = $this->createLoginAttemptsTimeRange(); + $this->blacklistedBruteForceIps = $this->createBlacklistedBruteForceIps(); + $this->whitelisteBruteForceIps = $this->createWhitelisteBruteForceIps(); + } + + private function createEnableBruteForceDetection() + { + return $this->makeSetting('enableBruteForceDetection', $default = true, FieldConfig::TYPE_BOOL, function (FieldConfig $field) { + $field->title = Piwik::translate('Login_SettingBruteForceEnable'); + $field->description = Piwik::translate('Login_SettingBruteForceEnableHelp'); + $field->uiControl = FieldConfig::UI_CONTROL_CHECKBOX; + }); + } + + private function createWhitelisteBruteForceIps() + { + return $this->makeSetting('whitelisteBruteForceIps', array(), FieldConfig::TYPE_ARRAY, function (FieldConfig $field) { + $field->title = Piwik::translate('Login_SettingBruteForceWhitelistIp'); + $field->uiControl = FieldConfig::UI_CONTROL_TEXTAREA; + $field->description = Piwik::translate('Login_HelpIpRange', array('1.2.3.4/24', '1.2.3.*', '1.2.*.*')); + $field->validators[] = new IpRanges(); + $field->transform = function ($value) { + if (empty($value)) { + return array(); + } + + $ips = array_map('trim', $value); + $ips = array_filter($ips, 'strlen'); + return $ips; + }; + }); + } + + private function createBlacklistedBruteForceIps() + { + return $this->makeSetting('blacklistedBruteForceIps', array(), FieldConfig::TYPE_ARRAY, function (FieldConfig $field) { + $field->title = Piwik::translate('Login_SettingBruteForceBlacklistIp'); + $field->uiControl = FieldConfig::UI_CONTROL_TEXTAREA; + $field->description = Piwik::translate('Login_HelpIpRange', array('1.2.3.4/24', '1.2.3.*', '1.2.*.*')); + $field->validators[] = new IpRanges(); + $field->transform = function ($value) { + if (empty($value)) { + return array(); + } + + $ips = array_map('trim', $value); + $ips = array_filter($ips, 'strlen'); + return $ips; + }; + }); + } + + private function createMaxFailedLoginsPerMinutes() + { + return $this->makeSetting('maxAllowedRetries', 20, FieldConfig::TYPE_INT, function (FieldConfig $field) { + $field->title = Piwik::translate('Login_SettingBruteForceMaxFailedLogins'); + $field->uiControl = FieldConfig::UI_CONTROL_TEXT; + $field->description = Piwik::translate('Login_SettingBruteForceMaxFailedLoginsHelp'); + }); + } + + private function createLoginAttemptsTimeRange() + { + return $this->makeSetting('allowedRetriesTimeRange', 60, FieldConfig::TYPE_INT, function (FieldConfig $field) { + $field->title = Piwik::translate('Login_SettingBruteForceTimeRange'); + $field->description = Piwik::translate('Login_SettingBruteForceTimeRangeHelp'); + $field->uiControl = FieldConfig::UI_CONTROL_TEXT; + }); + } + + public function isWhitelistedIp($ipAddress) + { + return $this->isIpInList($ipAddress, $this->whitelisteBruteForceIps->getValue()); + } + + public function isBlacklistedIp($ipAddress) + { + return $this->isIpInList($ipAddress, $this->blacklistedBruteForceIps->getValue()); + } + + private function isIpInList($ipAddress, $ips) + { + if (empty($ipAddress)) { + return false; + } + + $ip = IP::fromStringIP($ipAddress); + + if (empty($ips)) { + return false; + } + + return $ip->isInRanges($ips); + } +} |