Or why not to add a delay... It is important to protect your WordPress website from brute-force attacks, and various security plugins exist for doing so. For the purpose of this article, I modified the WordPress Login Delay plugin (nowadays called Login Delay Shield) with a fixed delay of three seconds for my wp-login.php page. This provides you with an easy to use method of protecting your WordPress login form, but do read the caveats!
A login delay with PHP's sleep() slows down brute-force attacks on wp-login.php, but every waiting request keeps a PHP process busy. Restricting access to wp-login.php by IP address is a better protection. Don't blatantly copy security code from other sites without proper testing.
Brute-force protection?
As Jeff Atwood writes on his blog:
Limiting the number of login attempts per user is security 101.
If you don't, you practically invite anyone to launch a dictionary attack on your site. Go read his post Dictionary Attacks 101 first.
WordPress Login Delay plugin
The following code can be used as a plugin (create wp-content/plugins/login-delay/login-delay.php), or in your theme's functions.php file.
<?php
/*
* Plugin Name: Saotn WordPress Login Delay
* Description: Saotn WordPress Login Delay plugin adds a three second delay
* when logging into WordPress. This slows down brute-force attacks on
* your website. However, it is not recommended to use sleep(), because
* a heavy brute-force attack will let all those POST requests sleep
* for the given amount of time.
* Original plugin name: WordPress Login Delay
* Original plugin URI: https://wordpress.org/plugins/wp-login-delay/
* Version: 1.0
* Author: Jan Reilink
* Author URI: https://www.saotn.org
* Original author: Michael Damoiseau
*/
if ( ! function_exists( 'saotn_auth_login' ) ) {
function saotn_auth_login( $user, $password ) {
$delay = 3;
sleep( $delay );
return $user;
}
add_filter( 'wp_authenticate_user', 'saotn_auth_login', 1, 2 );
}
Here we use add_filter() and the wp_authenticate_user filter hook to add a simple delay to our WordPress login page. The closing ?> tag is omitted on purpose: in a PHP-only file it prevents accidental whitespace output. Please read the description in the code carefully.
Login delay caveats
It is not recommended to use sleep() in your code. The PHP process simply sleeps for the configured time: during a brute-force attack of 1000 requests, 1000 PHP processes sleep for three seconds each. That makes a login delay a denial-of-service risk of its own.
It is better to only allow your own IP address access to /wp-login.php. See my WordPress web.config for an example on IIS, or use a captcha protection.
Block unwanted traffic before it reaches PHP at all: use HackRepair.com's Bad Bots blocklist in web.config for IIS, filter web traffic with blacklists, and read about 4 important security measures for Windows Server & IIS 10.
The code is provided "as-is", just to show you different angles of doing things differently than a lot of plugins do.