Last active
December 16, 2015 05:29
-
-
Save etiennetremel/5384999 to your computer and use it in GitHub Desktop.
Prevent Mass WordPress Login Attacks by setting locking the system when login fail.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* CLASS LIMIT LOGIN ATTEMPTS | |
* Prevent Mass WordPress Login Attacks by setting locking the system when login fail. | |
* To be added in functions.php or as an external file. | |
*/ | |
if ( ! class_exists( 'Limit_Login_Attempts' ) ) { | |
class Limit_Login_Attempts { | |
var $failed_login_limit = 3; //Number of authentification accepted | |
var $lockout_duration = 1800; //Stop authentification process for 30 minutes: 60*30 = 1800 | |
var $transient_name = 'attempted_login'; //Transient used | |
public function __construct() { | |
add_filter( 'authenticate', array( $this, 'check_attempted_login' ), 30, 3 ); | |
add_action( 'wp_login_failed', array( $this, 'login_failed' ), 10, 1 ); | |
} | |
/** | |
* Lock login attempts of failed login limit is reached | |
*/ | |
public function check_attempted_login( $user, $username, $password ) { | |
if ( get_transient( $this->transient_name ) ) { | |
$datas = get_transient( $this->transient_name ); | |
if ( $datas['tried'] >= $this->failed_login_limit ) { | |
$until = get_option( '_transient_timeout_' . $this->transient_name ); | |
$time = $this->when( $until ); | |
return new WP_Error( 'too_many_tried', sprintf( __( '<strong>ERROR</strong>: You have reached authentification limit, you will be able to try again in %1$s.' ) , $time ) ); | |
} | |
} | |
return $user; | |
} | |
/** | |
* Add transient | |
*/ | |
public function login_failed( $username ) { | |
if ( get_transient( $this->transient_name ) ) { | |
$datas = get_transient( $this->transient_name ); | |
$datas['tried']++; | |
if ( $datas['tried'] <= $this->failed_login_limit ) | |
set_transient( $this->transient_name, $datas , $this->lockout_duration ); | |
} else { | |
$datas = array( | |
'tried' => 1 | |
); | |
set_transient( $this->transient_name, $datas , $this->lockout_duration ); | |
} | |
} | |
/** | |
* Return difference between 2 given dates | |
* @param int $time Date as Unix timestamp | |
* @return string Return string | |
*/ | |
private function when( $time ) { | |
if ( ! $time ) | |
return; | |
$right_now = time(); | |
$diff = abs( $right_now - $time ); | |
$second = 1; | |
$minute = $second * 60; | |
$hour = $minute * 60; | |
$day = $hour * 24; | |
if ( $diff < $minute ) | |
return floor( $diff / $second ) . ' secondes'; | |
if ( $diff < $minute * 2 ) | |
return "about 1 minute ago"; | |
if ( $diff < $hour ) | |
return floor( $diff / $minute ) . ' minutes'; | |
if ( $diff < $hour * 2 ) | |
return 'about 1 hour'; | |
return floor( $diff / $hour ) . ' hours'; | |
} | |
} | |
} | |
//Enable it: | |
new Limit_Login_Attempts(); | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment