Limit Failed Login Attempts
Temporarily blocks an IP address after 5 failed logins within 15 minutes. A lightweight brute-force guard with no settings screen.
Opens WPIDE on
Code
$wpide_login_limit = array(
'attempts' => 5,
'window' => 15 * MINUTE_IN_SECONDS,
);
$wpide_login_key = function () {
$ip = isset( $_SERVER['REMOTE_ADDR'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) : 'unknown';
return 'wpide_login_fail_' . md5( $ip );
};
add_filter( 'authenticate', function ( $user, $username ) use ( $wpide_login_limit, $wpide_login_key ) {
if ( empty( $username ) ) {
return $user;
}
if ( (int) get_transient( $wpide_login_key() ) >= $wpide_login_limit['attempts'] ) {
return new WP_Error(
'wpide_too_many_attempts',
sprintf( '<strong>Error:</strong> Too many failed login attempts. Please try again in %d minutes.', (int) ceil( $wpide_login_limit['window'] / MINUTE_IN_SECONDS ) )
);
}
return $user;
}, 99, 2 );
add_action( 'wp_login_failed', function ( $username, $error = null ) use ( $wpide_login_limit, $wpide_login_key ) {
if ( is_wp_error( $error ) && 'wpide_too_many_attempts' === $error->get_error_code() ) {
return;
}
$key = $wpide_login_key();
set_transient( $key, (int) get_transient( $key ) + 1, $wpide_login_limit['window'] );
}, 10, 2 );
add_action( 'wp_login', function () use ( $wpide_login_key ) {
delete_transient( $wpide_login_key() );
} );
Notes
Behind a proxy or CDN, REMOTE_ADDR may be the proxy address; configure your server to pass the real visitor IP. Do not combine with another login limiter.
How to add this snippet
- Install WPIDE on your WordPress site (it is free) and open Code Snippets.
- Use snippet above adds it from the library in one click. Or copy the code into a new snippet with the same code type.
- It is added inactive: review the code and settings, then switch it on.