WordPressWebsite security

WordPress Security Checklist for Small Sites

7 min read

A lot of site owners assume that once the theme and plugins are in place and the site is live, the job is finished. Almost every attack on WordPress is fully automated: bots spend all day scanning for out-of-date plugins, login pages and weak passwords. They do not care how big your company is, only whether you left a gap. The good news is that automated attacks mostly go after easy targets, so getting the basics right takes you off the list. The checklist below splits into pre-launch configuration and post-launch maintenance, with items you can tick off in each part.

1. Core, themes and plugins: update first, then cut down

Out-of-date components are the most common reason WordPress sites get broken into, corresponding to A06 in the OWASP Top 10, use of components with known vulnerabilities. Attackers work from public vulnerability databases. A site that is one step behind on updates is a ready-made target.

The rhythm can be simple. Pick a day each month to check for new versions, and apply anything flagged as a security release quickly rather than holding it until the next round. Take a full backup before you start, work in quiet hours, or run the updates on a staging copy first. That way a layout that breaks after an update is not a crisis.

Cutting down matters as much as updating. Delete plugins and themes you will not be using in the near future rather than deactivating them. Keep one theme in use plus one official default as a fallback, and nothing else. Clear out the test pages and sample content left over from installation, along with files like readme.html that give away your version number.

2. Login hardening: shutting down brute force

wp-login.php is the door bots knock on most, working through dictionary lists one credential pair at a time. The aim at this layer is to make guessing unprofitable.

Start by replacing the default account. Do not use admin, and do not use your domain name as the administrator username. If admin already exists, create a second administrator account, confirm you can log in with it, then delete admin. Passwords should be at least 16 characters, randomly generated, kept in a password manager, and never shared with another service.

Next, add something beyond the password. Turn on two-factor authentication in the admin area and require it for every administrator and editor at minimum. A password that does get guessed is useless without the second factor.

Third, make the guessing itself unworkable. Limit login attempts, for example locking the account for a period after five consecutive failures, and record the source IP while you are at it. Then change or hide the default login path, since most automated tools only know wp-login.php and will move to the next target when they cannot find the door. If the site has no app or external integration relying on it, turn XML-RPC off as well: that is another entry point commonly used to amplify brute force attempts.

3. User roles and least privilege

On plenty of sites everyone is an administrator, which is the same as handing out keys to the whole building. The built-in WordPress roles exist for least privilege: each person gets only what their work actually requires. Fewer accounts with lower privileges means a smaller mess when one of them is taken over.

RoleWho it suitsWhat they can do
AdministratorPeople who genuinely need to install plugins and change settings, as few as possibleSite settings, plugins and themes, user management
EditorWhoever owns content quality and reviews other people's draftsPublish and edit anyone's posts
AuthorInternal staff who write regularlyPublish and manage their own posts
ContributorOutside writersWrite and submit for review, but not publish
SubscriberPeople who only need to log in to readManage their own profile

Two things follow the role split. First, audit the user list periodically and disable or delete accounts the day someone leaves or a project ends, rather than keeping them in case they come in useful. Second, never let several people share one login, or you will have no way to trace who did what and from where when something goes wrong.

4. File permissions, database prefix, and the built-in code editor

This part sits at the hosting layer and mostly belongs to pre-launch setup. If it is unfamiliar territory, hand the items below to a developer or your hosting provider, who will recognise them. There are three goals. Restrict which files can be rewritten, so the code cannot be altered quietly. Change the database table names to sidestep automated attacks that assume the defaults. And turn off the admin editor that lets someone change code directly, so a stolen administrator account still cannot touch your code.

Five settings to hand to a developer

  • Directories at 755, files at 644. Tighten wp-config.php further, to 640 or 600, since it holds the database password.
  • Do not leave the database table prefix as wp_. Use one with a random component, for example wp_a7x_.
  • Disable the built-in file editor. Add define('DISALLOW_FILE_EDIT', true); to wp-config.php.
  • Rotate the authentication keys (SALT). Generate a fresh set with the official generator and paste them into wp-config.php. Every existing login session is invalidated.
  • Block or restrict PHP execution in the uploads directory. If someone does manage to upload a backdoor file, this stops it running.

5. SSL and the basic security headers

HTTPS is the baseline now. It is not only about SEO and avoiding browser warnings, it is about login credentials not being readable in transit. A certificate from Let's Encrypt or similar is fine. What matters is configuring automatic renewal, so the whole site does not start throwing warnings the day somebody forgets.

Installing the certificate is half the work. You also need a site-wide redirect from HTTP to HTTPS, and the WordPress address settings changed to https, or you end up with pages that are half encrypted and half not. Then add the HSTS header (Strict-Transport-Security) so browsers remember the site is encrypted only.

Two more instructions for the browser are cheap and effective: X-Content-Type-Options and X-Frame-Options. They shut down the common trick of embedding your site inside someone else's page to harvest clicks. With all of it in place, run the site through a tool such as SSL Labs to confirm the certificate and protocol settings are sound.

6. Off-site backups and restore tests

A backup is the only thing that saves you after a compromise, but having backups and being able to restore are two different things. Too many people keep the backup files on the same server, so the backup dies with the host. Others have never restored one and find out the files are corrupt on the day it counts.

So a backup has to satisfy several conditions at once. Both the database and the files need to be included, uploads, theme and plugins among them, since only one of the two will not rebuild a working site. The storage location has to be somewhere else: another cloud, another server, anywhere that is not living with the site. Retention has to span several points in time, because a planted backdoor often goes unnoticed for a while, and if you keep only the latest copy that copy may already be dirty. How often you back up follows how often your content changes.

7. Choosing plugins, and a basic outer wall (the WAF idea)

Plugins are the best and the most dangerous thing about WordPress. One plugin of unknown origin or long abandoned is enough to drag the whole site down or open a hole. Choosing one is not a matter of searching and installing. A few things are worth checking first.

Three things to check before installing

  • Where it came from. Download only from the official plugin directory or the vendor's own site. Nulled plugins have nearly always been tampered with, and the licence fee you saved gets collected some other way.
  • When it was last updated. Anything untouched for more than a year should be treated with caution or replaced, because it usually means the author has moved on and nobody will be fixing the next vulnerability.
  • Install count and reviews. Prefer plugins that are actively maintained, with a named author and a support channel. An obscure plugin is not necessarily a bad one, but you are the party carrying the risk.

Once everything is installed, you can add an outer wall. A web application firewall (WAF) works like a filter in front of the site, blocking obvious malicious requests and automated scanning before they reach WordPress at all. Cloud-based and plugin-based options both exist. Turn on login protection and malicious traffic logging at the same time, so you get an alert when something is off and can reconstruct events afterwards.

To be straight about it, no tool can guarantee you will never be hacked. A WAF reduces risk, it does not remove it. What keeps working over time is the earlier items: updates, a lean install, strong passwords, backups. Every extra plugin widens the attack surface, so it is worth asking every few months whether each one is still needed.

Security is never finished, and this checklist does not stay ticked forever. What it does is move you off the list of easy targets automated attacks prefer. The rest is ongoing updates, backups and monitoring. If you have no time to watch all of that every month, handing maintenance to someone is usually cheaper than calling for help after an incident.

Common questions

Does a WordPress site have to run a security plugin? What happens without one?
It is not compulsory, but at minimum something covering login protection and malicious traffic detection is well worth having. Updates, strong passwords, two-factor authentication and backups can all be done without a plugin, and the value of a security plugin is in centralising the management and warning you early. Going without does not mean you will be hacked, but you lose an outer wall and an early warning, and the odds of an automated attack landing go up noticeably.
A WordPress site has been hacked, with the home page altered or ads injected. What is the first step?
Do not start deleting things. First preserve the site as it stands and take it offline or into maintenance mode so it stops serving malicious content. Then restore from a clean off-site backup, and immediately after the restore, update core and every plugin and change all passwords and database keys. If you cannot find the entry point, the site tends to get hit again shortly after the restore, and that is the point to bring in help for containment and root cause work so you know the backdoors are genuinely gone.
If I change the wp-login path and limit login attempts, is brute force no longer a problem?
It drops dramatically, but nothing is absolute. Hiding the login page and capping attempts stops the large majority of bots that only know wp-login.php, which cuts the noise a lot. What actually decides the outcome is password strength and two-factor authentication. Changing the path only means an attacker cannot find the door. A strong password plus a second factor is what keeps it shut once they do. Doing both together works best.

Read next