Limit login attempts
After 5 failed logins from the same IP address in 15 minutes, that address has to wait 15 minutes before trying again. Slows down password guessing.
<?php
// Change these three numbers to suit your site.
$snipfire_limit = 5; // Failed attempts allowed…
$snipfire_window = 15 * MINUTE_IN_SECONDS; // …within this time…
$snipfire_key = static function () {
// REMOTE_ADDR: behind Cloudflare or a proxy, make sure your host passes the visitor's real IP.
$ip = isset( $_SERVER['REMOTE_ADDR'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) : '';
return 'snipfire_login_' . md5( $ip );
};
add_action(
'wp_login_failed',
static function () use ( $snipfire_key, $snipfire_window ) {
$key = $snipfire_key();
set_transient( $key, (int) get_transient( $key ) + 1, $snipfire_window );
}
);
add_filter(
'authenticate',
static function ( $user ) use ( $snipfire_key, $snipfire_limit ) {
if ( (int) get_transient( $snipfire_key() ) >= $snipfire_limit ) {
return new WP_Error( 'snipfire_locked', __( '<strong>Error:</strong> Too many failed login attempts. Please try again in 15 minutes.' ) );
}
return $user;
},
99
);
add_action(
'wp_login',
static function () use ( $snipfire_key ) {
delete_transient( $snipfire_key() );
}
);
Good to know
The wait starts over with each new failed attempt. A security plugin or your host’s firewall does this more thoroughly; this is a light, no-plugin version.
In these packs
- Login and security extras: Limit login attempts, email-only logins, a registration spam trap and more hardening.