Browse Source

#137 Non-user based DDoS check

added a new table for login_attempts (in both SQL files)
added 2 config vars `login_attempts`(db) & `remove_successful_attempts`
changed function `reset_login_attempts()` (removed user_id and changed where to ip_address and timestamp from user_id only)
changed function `update_login_attempts()` (removed user_id and changed where to ip_address and timestamp from email/user_id only)
changed function `login()` (removed arguments from changed functions, added abilty to enable/disable removing login attempt after successful login)
develop
REJack 9 years ago
parent
commit
34f66afe5e
  1. 10
      application/config/aauth.php
  2. 74
      application/libraries/Aauth.php
  3. 15
      sql/Aauth_v2.sql
  4. 15
      sql/Aauth_v2_BCrypt.sql

10
application/config/aauth.php

@ -31,6 +31,7 @@ defined('BASEPATH') OR exit('No direct script access allowed');
| ['perm_to_user'] The table which contains permissions for users
| ['pms'] The table which contains private messages
| ['user_variables'] The table which contains users variables
| ['login_attempts'] The table which contains login attempts
|
| ['remember'] Remember time elapsed after connecting and automatic LogOut
|
@ -49,11 +50,12 @@ defined('BASEPATH') OR exit('No direct script access allowed');
| ['totp_active'] The Time-based One-time Password Algorithm
| ['totp_only_on_ip_change'] TOTP only on IP Change
| ['totp_reset_over_reset_password'] TOTP reset over reset Password
| ['totp_two_step_login'] enables TOTP two step login
| ['totp_two_step_login'] Enables/Disables TOTP two step login
| ['totp_two_step_login_redirect'] Redirect path to TOTP Verification page used by control() & is_allowed()
|
| ['max_login_attempt'] Login attempts time interval (default 10 times in one hour)
| ['max_login_attempt_time_period'] Period of time for max login attempts (default "5 minutes")
| ['remove_successful_attempts'] Enables/Disables removing login attempt after successful login
|
| ['login_with_name'] Login Identificator, if TRUE username needed to login else email address.
|
@ -66,8 +68,8 @@ defined('BASEPATH') OR exit('No direct script access allowed');
| ['verification_link'] Link for verification without site_url or base_url
| ['reset_password_link'] Link for reset_password without site_url or base_url
|
| ['hash'] Name of selected hashing algorithm (e.g. "md5", "sha256", "haval160,4", etc..)
| Please, run hash_algos() for know your all supported algorithms
| ['hash'] Name of selected hashing algorithm (e.g. "md5", "sha256", "haval160,4", etc..)
| Please, run hash_algos() for know your all supported algorithms
| ['use_password_hash'] True to use PHP's own password_hash() function with BCrypt, needs PHP5.5 or higher
| ['password_hash_algo'] password_hash algorithm (PASSWORD_DEFAULT, PASSWORD_BCRYPT) for details see http://php.net/manual/de/password.constants.php
| ['password_hash_options'] password_hash options array for details see http://php.net/manual/en/function.password-hash.php
@ -93,6 +95,7 @@ $config_aauth["default"] = array(
'perm_to_user' => 'aauth_perm_to_user',
'pms' => 'aauth_pms',
'user_variables' => 'aauth_user_variables',
'login_attempts' => 'aauth_login_attempts',
'remember' => ' +3 days',
@ -116,6 +119,7 @@ $config_aauth["default"] = array(
'max_login_attempt' => 10,
'max_login_attempt_time_period' => "5 minutes",
'remove_successful_attempts' => true,
'login_with_name' => false,

74
application/libraries/Aauth.php

@ -174,7 +174,7 @@ class Aauth {
$row = $query->row();
// only email found and login attempts exceeded
if ($query->num_rows() > 0 && $this->config_vars['ddos_protection'] && ! $this->update_login_attempts($row->email)) {
if ($query->num_rows() > 0 && $this->config_vars['ddos_protection'] && ! $this->update_login_attempts()) {
$this->error($this->CI->lang->line('aauth_error_login_attempts_exceeded'));
return FALSE;
@ -352,7 +352,10 @@ class Aauth {
// update last login
$this->update_last_login($row->id);
$this->update_activity();
$this->reset_login_attempts($row->id);
if($this->config_vars['remove_successful_attempts'] == TRUE){
$this->reset_login_attempts();
}
return TRUE;
}
@ -536,15 +539,18 @@ class Aauth {
/**
* Reset last login attempts
* Sets a users 'last login attempts' to null
* @param int $user_id User id to reset
* Removes a Login Attempt
* @return bool Reset fails/succeeds
*/
public function reset_login_attempts($user_id) {
$data['login_attempts'] = null;
$this->aauth_db->where('id', $user_id);
return $this->aauth_db->update($this->config_vars['users'], $data);
public function reset_login_attempts() {
$ip_address = $this->CI->input->ip_address();
$this->aauth_db->where(
array(
'ip_address'=>$ip_address,
'timestamp >='=>strtotime("-".$this->config_vars['max_login_attempt_time_period'])
)
);
return $this->aauth_db->delete($this->config_vars['login_attempts']);
}
/**
@ -645,34 +651,38 @@ class Aauth {
//tested
/**
* Update login attempt and if exceeds return FALSE
* Update user's last login attemp date and number date
* @param string $email User email
* @return bool
*/
public function update_login_attempts($email) {
$user_id = $this->get_user_id($email);
$query = $this->aauth_db->where('id', $user_id);
$query = $this->aauth_db->get( $this->config_vars['users'] );
$row = $query->row();
$data = array();
$data['last_login_attempt'] = date("Y-m-d H:i:s");
public function update_login_attempts() {
$ip_address = $this->CI->input->ip_address();
$query = $this->aauth_db->where(
array(
'ip_address'=>$ip_address,
'timestamp >='=>strtotime("-".$this->config_vars['max_login_attempt_time_period'])
)
);
$query = $this->aauth_db->get( $this->config_vars['login_attempts'] );
if (strtotime($row->last_login_attempt) > strtotime("-".$this->config_vars['max_login_attempt_time_period'])) {
if($query->num_rows() == 0){
$data = array();
$data['ip_address'] = $ip_address;
$data['timestamp']= date("Y-m-d H:i:s");
$data['login_attempts']= 1;
$this->aauth_db->insert($this->config_vars['login_attempts'], $data);
return TRUE;
}else{
$row = $query->row();
$data = array();
$data['timestamp'] = date("Y-m-d H:i:s");
$data['login_attempts'] = $row->login_attempts + 1;
} else {
$data['login_attempts'] = 1;
}
$this->aauth_db->where('id', $user_id);
$this->aauth_db->update($this->config_vars['users'], $data);
$this->aauth_db->where('id', $row->id);
$this->aauth_db->update($this->config_vars['login_attempts'], $data);
if ( $data['login_attempts'] > $this->config_vars['max_login_attempt'] ) {
return FALSE;
} else {
return TRUE;
if ( $data['login_attempts'] > $this->config_vars['max_login_attempt'] ) {
return FALSE;
} else {
return TRUE;
}
}
}

15
sql/Aauth_v2.sql

@ -160,3 +160,18 @@ CREATE TABLE `aauth_group_to_group` (
-- Records of aauth_perm_to_group
-- ----------------------------
-- ----------------------------
-- Table structure for `aauth_login_attempts`
-- ----------------------------
CREATE TABLE IF NOT EXISTS `aauth_login_attempts` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`ip_address` varchar(39) DEFAULT '0',
`timestamp` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`login_attempts` tinyint(2) DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- ----------------------------
-- Records of aauth_login_attempts
-- ----------------------------

15
sql/Aauth_v2_BCrypt.sql

@ -160,3 +160,18 @@ CREATE TABLE `aauth_group_to_group` (
-- Records of aauth_perm_to_group
-- ----------------------------
-- ----------------------------
-- Table structure for `aauth_login_attempts`
-- ----------------------------
CREATE TABLE IF NOT EXISTS `aauth_login_attempts` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`ip_address` varchar(39) DEFAULT '0',
`timestamp` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`login_attempts` tinyint(2) DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- ----------------------------
-- Records of aauth_login_attempts
-- ----------------------------

Loading…
Cancel
Save