How I Keep Dozens of WordPress Sites on One Server Secure

The more popular a system becomes, the more attractive it becomes to attackers. WordPress is the most widely used CMS in the world, and WordPress sites on the public internet are attacked every day in many different ways. A lot of our clients host their WordPress sites on servers we maintain, so keeping those sites secure is a serious responsibility.

The main types of attacks aimed at WordPress

Most attacks against WordPress are not handcrafted one-off attacks. Attackers usually scan large numbers of sites and then automate the next step if they find a useful weakness. There are simply too many WordPress sites on the internet for manual one-by-one attacks to be efficient.

Brute-force attacks on FTP, server accounts, and WordPress admin accounts

Brute-force attacks are one of the oldest and least sophisticated attack types, but they still happen constantly. The good news is that they are also among the easiest to defend against if basic security rules are followed.

  • FTP sends passwords in plain text, so it is a weak point. For that reason, we avoid opening FTP entirely and deploy code through Git instead.
  • To deal with repeated server-login failures, our CentOS servers use tools such as banhost so the attacking IP is blocked automatically after several failed attempts.
  • For WordPress administrator accounts, we ask clients to use strong passwords and never keep the default username admin. Those two steps alone prevent a huge amount of trouble.

On top of that, services such as Fail2ban can help block brute-force behavior automatically. Even so, there is still the possibility that an administrator password could leak, which is why additional hardening is needed too.

Code injection through server or WordPress vulnerabilities

This kind of attack is very common. In many cases the attacker is trying to inject advertising links or other malicious content into the WordPress site. Based on our own experience, a large share of those mass-injection attempts has come from traffic originating in Russia.

Our defense is to make all WordPress core files, themes, and plugins read-only. Even if WordPress or a plugin has an unpatched vulnerability, the attacker cannot modify the application files directly. The writable area is limited mainly to wp-content/uploads, which protects normal site operation while still letting users upload content.

Denial-of-service (DDoS) attacks

DDoS attacks are different. They are usually targeted at a specific site and are often motivated by personal disputes or malicious competition. The idea is to create so much fake traffic that legitimate visitors can no longer reach the site.

Although some filtering can be done on the server, the most effective help in that situation usually comes from the hosting provider or upstream network protection.

Edit wp-config.php to disable code editing in the dashboard

Earlier I mentioned the question of what happens if a site administrator’s password leaks. One of our standard measures is to disable theme and plugin editing in the WordPress dashboard. Site owners can still view installed themes and plugins, enable and disable plugins, and switch themes, but they cannot edit code or install new plugins directly from the admin area.

That also reduces the risk that an inexperienced user will accidentally break the site while editing PHP code in the back end. Add the following lines to wp-config.php:

// Do not allow file editing or modifications from the dashboard
define('DISALLOW_FILE_EDIT', true);
define('DISALLOW_FILE_MODS',true);

Many brute-force attacks are launched purely to inject hidden advertisement links or other unwanted code. Disabling dashboard code editing is a good defensive step even if the site seems fine at the moment.

Regularly inspect user-generated content and remove files that should not exist

For example, under normal circumstances there should never be PHP files inside the uploads directory. If such files appear, they are extremely suspicious. We back them up outside the web root first, then remove them.

Because all of our sites use URL rewriting, normal visitors also have very little reason to request random PHP files directly. Reviewing access logs regularly and watching for direct requests to unusual PHP files makes it much easier to spot injected code or probing activity.

Maintain off-site backups on a schedule in case of disasters

Our backup strategy is to back up code files off-site every week and back up databases off-site every day. Even if a server is lost completely, the data loss is usually limited to about one day.

For off-site backup we use a VPS-to-Dropbox script that is easy to find online. Because WordPress supports two-factor authentication, the backup workflow itself can still be kept relatively safe.

Keep WordPress and plugins updated

Timely updates are a necessary part of WordPress security. On one or two sites, updating manually in the dashboard is fine. On dozens of sites, it becomes a time sink very quickly.

Because we disable direct code modification in the dashboard, WordPress and plugin updates appear as notifications but are not applied automatically. To solve that, we wrote a Bash script that downloads the latest WordPress files and updates each site by replacing the relevant files automatically.

Summary

With the measures above in place, the sites on our servers have stayed in much better shape. Attacks still appear in access logs, but they have not caused the same problems they used to. Of course, these measures mainly defend against broad automated attacks. A determined and highly skilled attacker is still a different category of risk entirely.

But for normal WordPress maintenance, a disciplined routine of hardening, monitoring, backup, and updates goes a very long way.

Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *