Last updated on September 25, 2023

Limit Login Attempts and Block IP Addresses

Don’t know where to add this snippet? Read our guide: How to add code snippets.

Enhance login security in WordPress.

The code snippet provided below demonstrates how to limit login attempts and block IP addresses in WordPress using the wpsnippets_limit_login_attempts() function. This function will track the number of failed login attempts made by a user and block their IP address after a certain threshold is reached.

function wpsnippets_limit_login_attempts() {
    $max_attempts = 3; // Maximum number of login attempts allowed
    $block_duration = 3600; // Block IP address for 1 hour (in seconds)

    if (isset($_SERVER['REMOTE_ADDR'])) {
        $ip_address = $_SERVER['REMOTE_ADDR'];
    } else {
        return;
    }

    $failed_attempts = get_transient('wpsnippets_failed_login_attempts_' . $ip_address);

    if (false === $failed_attempts) {
        $failed_attempts = 0;
    }

    if ($failed_attempts >= $max_attempts) {
        // Block the IP address
        $blocked_ips = get_option('wpsnippets_blocked_ips', array());
        $blocked_ips[$ip_address] = time() + $block_duration;
        update_option('wpsnippets_blocked_ips', $blocked_ips);

        // Clear the failed attempts count
        delete_transient('wpsnippets_failed_login_attempts_' . $ip_address);

        // Redirect the user to a custom error page or display a message
        wp_redirect(home_url('/custom-error-page/'));
        exit;
    }

    // Increase the failed attempts count
    $failed_attempts++;
    set_transient('wpsnippets_failed_login_attempts_' . $ip_address, $failed_attempts, $block_duration);
}
add_action('wp_login_failed', 'wpsnippets_limit_login_attempts');

Use case: This code snippet can be useful in enhancing the security of your WordPress website by limiting the number of failed login attempts from a specific IP address. It helps prevent brute-force attacks and unauthorized access to user accounts.

Note: Make sure to replace /custom-error-page/ in the wp_redirect() function with the URL of your custom error page or the desired action you want to take when the maximum login attempts are exceeded.

Examples

Example 1: Limit Login Attempts with a Custom Function

This use case demonstrates how to limit the number of login attempts a user can make before being locked out of the WordPress site. The code example below shows a custom PHP function wpsnippets_limit_login_attempts() that uses the wp_login_failed action hook to track failed login attempts and block the user after a certain number of attempts.

function wpsnippets_limit_login_attempts() {
    $max_attempts = 3;
    $lockout_duration = 10 * MINUTE_IN_SECONDS;

    if (isset($_COOKIE['login_attempts'])) {
        $attempts = intval($_COOKIE['login_attempts']);
        $attempts++;

        if ($attempts >= $max_attempts) {
            setcookie('login_attempts', $attempts, time() + $lockout_duration, '/');
            wp_die('Too many login attempts. Please try again after ' . $lockout_duration / MINUTE_IN_SECONDS . ' minutes.');
        } else {
            setcookie('login_attempts', $attempts, time() + $lockout_duration, '/');
        }
    } else {
        setcookie('login_attempts', 1, time() + $lockout_duration, '/');
    }
}
add_action('wp_login_failed', 'wpsnippets_limit_login_attempts');

The wpsnippets_limit_login_attempts() function checks if a cookie named login_attempts exists. If it does, it increments the value and checks if the maximum number of attempts has been reached. If the maximum attempts are reached, it sets a new cookie with an expiration time and displays an error message. If the maximum attempts are not reached, it updates the cookie with the new value. If the cookie doesn’t exist, it sets it to 1.

Example 2: Block IP Addresses with .htaccess

This use case demonstrates how to block specific IP addresses from accessing your WordPress site using the .htaccess file. The code example below shows how to add IP addresses to the .htaccess file to deny access.

<Files wp-login.php>
order deny,allow
deny from 192.168.0.1
deny from 10.0.0.0/8
allow from all
</Files>

In the code example, the <Files> directive is used to target the wp-login.php file. The order deny,allow directive specifies that the deny rules should be processed before the allow rule. The deny from directive is used to specify the IP addresses that should be blocked. In this example, IP address 192.168.0.1 and the entire 10.0.0.0/8 subnet are blocked. The allow from all directive allows access to all other IP addresses.

Example 3: Block IP Addresses with a Custom Function

This use case demonstrates how to block specific IP addresses from accessing your WordPress site using a custom PHP function. The code example below shows a custom PHP function wpsnippets_block_ip_address() that uses the login_init action hook to check the user’s IP address and block access if it matches a specified list of blocked IP addresses.

function wpsnippets_block_ip_address() {
    $blocked_ips = array(
        '192.168.0.1',
        '10.0.0.0/8'
    );
    $user_ip = $_SERVER['REMOTE_ADDR'];
    if (in_array($user_ip, $blocked_ips)) {
        wp_die('Access denied.');
    }
}
add_action('login_init', 'wpsnippets_block_ip_address');

The wpsnippets_block_ip_address() function defines an array of blocked IP addresses. It then retrieves the user’s IP address using $_SERVER['REMOTE_ADDR']. If the user’s IP address is found in the array of blocked IP addresses, it displays an error message using wp_die(), effectively blocking access to the site.

Last updated on September 25, 2023. Originally posted on October 16, 2023.

Leave a Reply