Of course we cannot always share details about our work with customers, but nevertheless it is nice to show our technical achievements and share some of our implemented solutions.
It's nothing new that Wordpress is currently world's most widely used content management system. The vast amount of possibilities (themes, plugins) makes Wordpress a great CMS for users without technical knowledge but also for developers and other users with advanced technical knowledge.
But this comes with a cost: The attack surface is huge. An attacker can simply crawl through the Internet, detect many Wordpress sites and can attack these sites. In the past we've already written articles how to protect your Wordpress site or how we analyzed Wordpress hacks.
The lesson at the end of a hack is (almost) always the same: It could have been prevented. By updating Wordpress (and all installed themes and plugins) and using secure login mechanisms (secure passwords, MFA), automated hack attempts will have a longer/harder time. But there's another improvement which can be done.
Taking a closer look at the default Wordpress login (usually on /wp-login.php), the login form shows up:
Of course this simple form can be used without manually entering data into the form fields. Scripts can simply POST data to /wp-login.php, trying millions of user/password combinations. The biggest problem however is how Wordpress itself (by default) reacts to a wrong login: The HTTP response code is still 200, even though the login failed due to a wrong username or wrong password or both.
This makes it hard for log analysis tools to detect malicious login attempts. Looking at the web server's access logs shows the same entries for a successful and an unsuccessful login:
127.0.0.1 - - [24/Sep/2022:12:05:49 +0200] "POST /wp-login.php HTTP/1.0" 200 2932 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36"
If at least wp-login.php would return a different HTTP status code, security tools such as fail2ban would be able to automatically block malicious client IP addresses.
This is where the "WP fail2ban" plugin comes into play. It doesn't change the HTTP status code on a failed login, but it creates a SYSLOG event which is logged in the server's system logs. The log message contains information about the client IP, the requested username and whether or not the login was successful.
Aug 24 06:58:49 irczsrvc23 wordpress(www.example.com): Authentication attempt for unknown user admin from 188.8.131.52
These log events can now be picked up by fail2ban, configured on the server, to pick up and correctly interpret these Wordpress log events. The client IP addresses will be automatically banned (= blocked) from the server if too many unsuccessful are detected.
Some might say that this can already be covered with Wordpress plugins, such as the Limit Login Attempts Reloaded plugin (we wrote about that), but such plugins will only protect this Wordpress installation from the attacker. The server itself, including potential other websites on the same web server, can still be attacked. With the fail2ban approach, the attacker is locked out on network level, making it impossible to continue the attacks with the same IP. Yes, the attacker can change the IP address, but it will definitely slow down the attacks.
After having successfully tested this security setup on a couple of Wordpress installations in the past few weeks, we decided to enable this malicious Wordpress login detection on all our dedicated LAMP servers by default, without a price increase.
In our monitoring we can see how many client IP addresses are currently blocked, due to malicious login detection from our WP fail2ban setup:
A server-side solution, such as this Wordpress fail2ban implementation and deployment across all LAMP servers, is usually done in the background and customers are mostly unaware what the security stack on the web servers look like. But in this example a collaboration between customers and the hosting provider is necessary. As Wordpress is installed and managed by our customers, the "WP fail2ban" plugin needs to be installed by our customers. Thanks to the great collaboration and exchange we have with all of our customers, this turned out to be easier than expected. And at the end all involved parties profit greatly from the enhanced security. A Win-win situation for all.
Infiniroot is a hosting and cloud provider, providing IT solutions with Open Source Software, in Switzerland. The managed dedicated environments can range from a single LAMP server, for example for a Wordpress site, up to a managed virtual Infrastructure surrounding a web application.