This ist part 2 of my mini series on setting up a WordPress site for my daughter’s primary school. In part 1, I covered the basic setup, including TLS and various security-related HTTP headers. In this post, I outline some steps specific to WordPress to secure your site. As I already introduced Cloudflare as a comfortable means of securing a site, I will continue to refer to Cloudflare in this post as well.
In order to provide just a little more security against automated attacks like botnets, you can add access restrictions using Cloudflare’s Web Application Firewall rules. Using these, you may e.g. restrict access to the admin panel depending on a request’s origin country. For WordPress, such a rule could look like this:
(ip.geoip.country ne "DE" and http.request.uri.path contains "/wp-admin/") or (ip.geoip.country ne "DE" and http.request.uri.path contains "/wp-login.php")
While a trained person can work around such a restriction fairly easily, it provides an additional layer of protection against untargeted, automated attacks. Users trying to make web requests to your WordPress admin panel just get the following page along with and HTTP 403 return code:
Multi Factor Authentication
The security of a site is determined by its weakest point. Setting up a site that is used by a number of people always comes with the risk of one user’s password being that weak point. Therefore, I was searching for a way to enable multi-factor authentication (specifically 2 factor authentication, 2FA). I settled using the plugin WP 2FA for this. It is maintained by a company that offers paid, security-related WordPress plugins, which gives me some confidence they are doing things right. Also, their support seemed quite knowledgeable, the configuration makes sense, and the plugin works as expected.
Caution: Mobile App Access
Out of curiosity, I tried logging in to my new site using the WordPress mobile app for iOS. While it worked flawlessly, I noticed it did not ask me for my second factor, but simply logged me in once I provided the correct password. Since this basically breaks the whole premise of 2FA, I contacted WP 2FA support. They quickly replied that they are aware of the issue, but have not yet found a solution to support 2FA when using the mobile app. Since we do not need the app, I decided to block it completely, so nobody can use it to circumvent 2FA.
After some network sniffing, I found the app uses a single endpoint on the site for all its requests, namely the file
xmlrpc.php. A quick web search brought up several results on how to disable this functionality either via an additional WordPress plugin, or via a filter in Apache web server. But since I was already using the Cloudflare firewall, I just added another rule to block all requests to that file:
(http.request.uri.path eq "/xmlrpc.php")
This effectively blocks login via the mobile app and therefore closes yet another entry point for possible credential stuffing attacks. With this rule in place, the app just displays an error trying to connect to the site.
Do you have additional tips on how to secure a simple WordPress site? Feel free to leave a comment. Part 3 of this series will cover the creation of a Content Security Policy (CSP) and enable logging for issues related to that.