2

I am adding cookie on login page using 'init' action-hook.

And than after login I check if this cookie exist in 'login_init' action-hook.

And also after user registration I check if this cookie exist in 'registration_errors' filter-hook.

Do I use proper hooks for pre-login and pre-registration actions?

code:

<?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()

Link to the plugin - https://dl.dropboxusercontent.com/u/1025327/share/security-protection-1.2.zip

  • 2
    Define "proper"? :) There are very few things for which "proper" hook is set in stone. Does it work for you? Do you have any specific concerns about this implementation? – Rarst Mar 23 '14 at 18:56
  • @Rarst It does not work for me because I add redirect to 'login_init' hook and it works on registration page too and that is why I am asking about it. – webvitaly Mar 23 '14 at 19:59
  • Please go back, file an edit, add all the needed info and show your current code. – kaiser Mar 23 '14 at 20:49
  • @kaiser thank you very much for your help. I added the code to the post. – webvitaly Mar 23 '14 at 21:24
4

Proper hooks for login and register actions:

<?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;
}
?>
  • 2
    Would you mind adding at least two lines of text or some comments in code to explain why this is snippets are helpful? – kaiser Apr 7 '14 at 5:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.