私は 'init'アクションフックを使用してログインページにクッキーを追加しています。
そして、ログイン後よりも、このクッキーが 'login_init'アクションフックに存在するかどうかをチェックします。
また、ユーザー登録後に、このCookieが 'registration_errors'フィルターフックに存在するかどうかを確認します。
ログイン前および登録前のアクションに適切なフックを使用しますか?
コード:
<?php
$securityprotection_send_brute_force_log_to_admin = true; // if true, than info about blocked brute-force attacks will be sent to admin email
$securityprotection_login_cookie_check = true; // if true, than cookie will be set on login screen and checked before login
$securityprotection_registration_cookie_check = true; // if true, than cookie will be set on registration screen and checked before registration
if ( ! function_exists( 'securityprotection_hooks' ) ) :
function securityprotection_hooks() {
add_action( 'init', 'securityprotection_set_login_cookie' );
add_action( 'login_init', 'securityprotection_login' );
add_filter( 'registration_errors', 'securityprotection_registration', 10, 3 );
}
securityprotection_hooks();
function securityprotection_set_login_cookie() {
global $securityprotection_login_cookie_check;
if( $securityprotection_login_cookie_check ) {
if( strtoupper( $_SERVER['REQUEST_METHOD']) == 'GET' and !isset( $_COOKIE['wordpress_secprot_cookie'] ) ) {
setcookie( 'wordpress_secprot_cookie', '1', time()+60*60*24*30, COOKIEPATH, COOKIE_DOMAIN ); // set cookie for a month
$_COOKIE['wordpress_secprot_cookie'] = '1';
}
}
}
function securityprotection_login() {
global $securityprotection_send_brute_force_log_to_admin, $securityprotection_login_cookie_check;
if( $securityprotection_login_cookie_check ) {
if( strtoupper( $_SERVER['REQUEST_METHOD'] ) == 'POST' and !isset( $_COOKIE['wordpress_secprot_cookie'] ) ) {
if ( $securityprotection_send_brute_force_log_to_admin ) { // if sending email to admin is enabled
$securityprotection_admin_email = get_option('admin_email'); // admin email
if ( !empty( $_SERVER['HTTP_CLIENT_IP'] ) ) { //check ip from share internet
$ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif ( !empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) { // to check ip is pass from proxy, also could be used ['HTTP_X_REAL_IP ']
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
$ip = $_SERVER['REMOTE_ADDR'];
}
$securityprotection_message_brute_force_info = '';
$securityprotection_message_brute_force_info .= 'IP : ' . $ip . "\r\n";
$securityprotection_message_brute_force_info .= 'HTTP_USER_AGENT : ' . $_SERVER['HTTP_USER_AGENT'] . "\r\n";
$securityprotection_message_brute_force_info .= 'REQUEST_URI : ' . $_SERVER['REQUEST_URI'] . "\r\n";
$securityprotection_message_brute_force_info .= 'HTTP_REFERER : ' . $_SERVER['HTTP_REFERER'] . "\r\n\r\n";
//$securityprotection_message_brute_force_info .= 'SERVER_PROTOCOL : ' . $_SERVER['SERVER_PROTOCOL'] . "\r\n";
//$securityprotection_message_brute_force_info .= 'REDIRECT_STATUS : ' . $_SERVER['REDIRECT_STATUS'] . "\r\n\r\n";
$securityprotection_message_brute_force_info .= 'POST vars:'."\r\n"; // lets see what POST vars brute-forcers try to submit
foreach ( $_POST as $key => $value ) {
$securityprotection_message_brute_force_info .= '$_POST['.$key. '] = '.$value."\r\n"; // .chr(13).chr(10)
}
$securityprotection_message_brute_force_info .= "\r\n\r\n";
$securityprotection_message = '';
$securityprotection_message .= $securityprotection_message_brute_force_info; // post, cookie and other data
$securityprotection_message .= $securityprotection_message_append;
$securityprotection_subject = 'Login brute-force on site ['.get_bloginfo( 'name' ).']'; // email subject
@wp_mail( $securityprotection_admin_email, $securityprotection_subject, $securityprotection_message ); // send log info to admin email
}
// many brute-force attacks are waiting for redirect or WordPress login cookies
// if we will fake redirect and login cookies than many brute-forcers will stop their attacks
securityprotection_set_fake_login_cookies(); // set fake login cookies
securityprotection_fake_redirect(); // fake admin dashboard redirect
}
}
}
function securityprotection_registration($errors, $sanitized_user_login, $user_email) {
global $securityprotection_send_brute_force_log_to_admin, $securityprotection_registration_cookie_check;
if( $securityprotection_registration_cookie_check ) {
if( strtoupper( $_SERVER['REQUEST_METHOD'] ) == 'POST' and !isset( $_COOKIE['wordpress_secprot_cookie'] ) ) {
if ( $securityprotection_send_brute_force_log_to_admin ) { // if sending email to admin is enabled
$securityprotection_admin_email = get_option('admin_email'); // admin email
if ( !empty( $_SERVER['HTTP_CLIENT_IP'] ) ) { //check ip from share internet
$ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif ( !empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) { // to check ip is pass from proxy, also could be used ['HTTP_X_REAL_IP ']
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
$ip = $_SERVER['REMOTE_ADDR'];
}
$securityprotection_message_brute_force_info = '';
$securityprotection_message_brute_force_info .= 'IP : ' . $ip . "\r\n";
$securityprotection_message_brute_force_info .= 'HTTP_USER_AGENT : ' . $_SERVER['HTTP_USER_AGENT'] . "\r\n";
$securityprotection_message_brute_force_info .= 'REQUEST_URI : ' . $_SERVER['REQUEST_URI'] . "\r\n";
$securityprotection_message_brute_force_info .= 'HTTP_REFERER : ' . $_SERVER['HTTP_REFERER'] . "\r\n\r\n";
$securityprotection_message_brute_force_info .= 'POST vars:'."\r\n"; // lets see what POST vars brute-forcers try to submit
foreach ( $_POST as $key => $value ) {
$securityprotection_message_brute_force_info .= '$_POST['.$key. '] = '.$value."\r\n"; // .chr(13).chr(10)
}
$securityprotection_message_brute_force_info .= "\r\n\r\n";
$securityprotection_message_brute_force_info .= 'COOKIE vars:'."\r\n"; // lets see what COOKIE vars brute-forcers try to submit
foreach ( $_COOKIE as $key => $value ) {
$securityprotection_message_brute_force_info .= '$_COOKIE['.$key. '] = '.$value."\r\n"; // .chr(13).chr(10)
}
$securityprotection_message_brute_force_info .= "\r\n\r\n";
$securityprotection_message = '';
$securityprotection_message .= $securityprotection_message_brute_force_info; // post, cookie and other data
$securityprotection_message .= $securityprotection_message_append;
$securityprotection_subject = 'Registration brute-force on site ['.get_bloginfo( 'name' ).']'; // email subject
@wp_mail( $securityprotection_admin_email, $securityprotection_subject, $securityprotection_message ); // send log info to admin email
$errors = new WP_Error();
$errors->add( 'security_protection_error', '<strong>ERROR</strong>: Security-protection registration error.' );
//securityprotection_set_fake_login_cookies(); // set fake login cookies
//securityprotection_fake_redirect(); // fake admin dashboard redirect
}
}
}
return $errors;
}
endif; // end of securityprotection_hooks()
if ( ! function_exists( 'securityprotection_plugin_meta' ) ) :
function securityprotection_plugin_meta( $links, $file ) { // add 'Plugin page' and 'Donate' links to plugin meta row
if ( strpos( $file, 'security-protection.php' ) !== false ) {
$links = array_merge( $links, array( '<a href="http://web-profile.com.ua/wordpress/plugins/security-protection/" title="Plugin page">Security-protection</a>' ) );
$links = array_merge( $links, array( '<a href="http://web-profile.com.ua/donate/" title="Support the development">Donate</a>' ) );
}
return $links;
}
add_filter( 'plugin_row_meta', 'securityprotection_plugin_meta', 10, 2 );
endif; // end of securityprotection_plugin_meta()
if ( ! function_exists( 'securityprotection_random_string_generator' ) ) :
function securityprotection_random_string_generator( $readable = 0, $length = 32 ) {
$random_string = '';
if( $readable ){ // create readable random string like 'suzuki'
$characters_b = 'bcdfghjklmnpqrstvwxz';
$characters_a = 'aeiouy';
$ab = 'b';
for( $i = 0; $i < $length; $i++ ) {
if( $ab == 'b' ){
$random_string .= $characters_b[ Rand( 0, strlen( $characters_b ) - 1 ) ];
$ab = 'a';
} else {
$random_string .= $characters_a[ Rand( 0, strlen( $characters_a ) - 1 ) ];
$ab = 'b';
}
}
} else { // create fully random string like 'q3WLtN'
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
for( $i = 0; $i < $length; $i++ ) {
$random_string .= $characters[ Rand( 0, strlen( $characters ) - 1) ];
}
}
return $random_string;
}
endif; // end of securityprotection_random_string_generator()
if ( ! function_exists( 'securityprotection_fake_redirect' ) ) :
function securityprotection_fake_redirect() { // fake admin dashboard redirect
//header("HTTP/1.0 403 Forbidden"); // correct redirect
$redirect_to = admin_url();
wp_safe_redirect($redirect_to); // redirect the brute-force bot to admin section to emulate that the password is cracked and some brute-forcers stop their attacks after such redirect :)
exit();
}
endif; // end of securityprotection_fake_redirect()
if ( ! function_exists( 'securityprotection_set_fake_login_cookies' ) ) :
function securityprotection_set_fake_login_cookies() { // set fake login cookies
$expiration = time() + 14 * DAY_IN_SECONDS;
$expire = $expiration + ( 12 * HOUR_IN_SECONDS );
$secure = '';
// login cookie names are located in wp-includes/default-constants.php:
// define('AUTH_COOKIE', 'wordpress_' . COOKIEHASH);
// define('LOGGED_IN_COOKIE', 'wordpress_logged_in_' . COOKIEHASH);
$cookie_name_random = securityprotection_random_string_generator();
$cookie_value_random = securityprotection_random_string_generator();
$auth_cookie_fake = 'wordpress_'.$cookie_name_random;
$logged_in_cookie_fake = 'wordpress_logged_in_'.$cookie_name_random;
setcookie($auth_cookie_fake, $cookie_value_random, $expire, COOKIEPATH, COOKIE_DOMAIN, $secure, true);
setcookie($logged_in_cookie_fake, $cookie_value_random, $expire, COOKIEPATH, COOKIE_DOMAIN, $secure, true);
}
endif; // end of securityprotection_set_fake_login_cookies()
プラグインへのリンク - https://dl.dropboxusercontent.com/u/1025327/share/security-protection-1.2.Zip
ログインおよび登録アクションのための適切なフック:
<?php
function custom_plugin_hooks() {
add_action( 'login_form', 'custom_plugin_form_inputs' );
add_filter( 'authenticate', 'custom_plugin_login_check', 100, 3 );
add_action( 'register_form', 'custom_plugin_form_inputs' );
add_action( 'register_post', 'custom_plugin_registration_check', 100, 3);
}
custom_plugin_hooks();
function custom_plugin_form_inputs() {
echo "\n".'<p>';
echo '<label>Custom input: <br />';
echo '<input type="text" name="custom-input" class="input" value="" />';
echo '</label></p>'."\n";
}
function custom_plugin_login_check($user, $username, $password) {
// user gave us valid username and password
if( !is_wp_error( $user ) ) {
if( !empty( $_POST ) ) {
if( $_POST['custom-input'] !== 'custom-value' ) {
$error = new WP_Error();
$error->add( 'custom-login-error', 'Login error.');
return $error;
}
}
}
return $user;
}
function custom_plugin_registration_check( $login, $email, $errors ) {
if( !empty( $_POST ) ) {
if( $_POST['custom-input'] !== 'custom-value' ) {
$errors->add( 'custom-registration-error', 'Registration error.');
}
}
return $errors;
}
?>