You are not being targeted, you are being scanned
It is tempting to assume a small organisation's website is not worth attacking. That reasoning does not apply, because almost none of this is manual. Automated tools scan continuously for known vulnerabilities in specific plugin and theme versions, and act on whatever they find.
The site's importance is irrelevant to the scanner. Only its version numbers matter.
Updates are the single highest-value habit
The overwhelming majority of WordPress compromises exploit vulnerabilities that had already been patched. The fix existed; it had simply not been applied.
Keep WordPress core, themes and plugins current. The one caveat is that updates occasionally break things, which is why they should be applied deliberately rather than blindly.
- Enable automatic updates for minor core releases
- Review major updates before applying them to a live site
- Take a backup immediately before any significant update
- Verify the site after updating, rather than assuming it went fine
Remove what you are not using
Deactivated plugins and unused themes still exist on the server, and a vulnerability in one can still be exploitable. Deactivation is not removal.
If you are not using it, delete it. This applies to the default themes shipped with WordPress that you have no intention of ever switching to.
Accounts and passwords
Weak credentials remain one of the most common ways in. The defence is straightforward and rarely implemented fully.
- No account named 'admin'
- Strong unique passwords, stored in a password manager
- Two-factor authentication on administrator accounts
- Give each person the lowest role that lets them do their job
- Remove accounts for people who have left, immediately rather than eventually
Backups only count if you have restored one
An untested backup is a hope, not a plan. Backup systems fail quietly in several ways: they stop running, they run but exclude the database, they store copies on the same server that just got compromised.
A usable backup regime means automated backups, stored somewhere separate from the site, and at least one restore that you have actually performed to confirm the process works.
- Automate backups of both files and database
- Store copies off-server
- Perform a test restore, then you know
Hosting and transport
Some responsibility sits below the application. A host that keeps PHP current, isolates accounts properly and provides SSL certificates is doing meaningful security work on your behalf. A cheap shared host running an end-of-life PHP version is a liability you cannot patch from inside WordPress.
HTTPS should be enforced site-wide, with HTTP traffic redirected rather than merely available.
Have a plan for the bad day
Know in advance who to contact, where the backups are, how to put the site into maintenance mode, and how to change every relevant password quickly.
Working that out calmly beforehand is considerably easier than working it out during an incident.
Written by Ntege Israel Charles, a Web Developer and WordPress Developer based in Kampala, Uganda. If any of this applies to a site you are responsible for, get in touch.