Most WordPress security checklists are a flat list of twenty toggles where "install a two-factor plugin" sits at the same priority as "rename your login URL." That framing is actively misleading, because the things that get sites hacked are not evenly distributed. In practice, the overwhelming majority of real WordPress compromises trace back to two causes: a known vulnerability in an out-of-date plugin or theme, and a weak or reused admin password that gets brute-forced or stuffed. Everything else is hardening — worth doing, but lower yield.
So this checklist is organized by attack surface, roughly in order of how often each one actually burns people. Fix the top two sections this week and you have eliminated most of your real risk. The rest is defense in depth.
1. Login and authentication (the credential-theft surface)
WordPress login pages get hammered constantly by automated credential-stuffing and brute-force bots. They are not targeting you; they are spraying every WordPress install on the internet. Your job is to make sure a correct guess is improbable and a flood of wrong ones gets cut off.
- Kill the
admin username. If any account is named admin or administrator, that is half the credential already known to the attacker. Create a fresh administrator with a non-obvious username, reassign content to it, and delete the old one. While you are at it, change your display name so it differs from your login slug — by default WordPress leaks the login name in author archive URLs.
- Use a real password, stored in a manager. Sixteen-plus random characters from a password manager, never reused anywhere else. Human-memorable passwords lose to modern stuffing lists; length and randomness are the only things that hold.
- Enforce two-factor on every admin and editor. This is the single highest-leverage control on the whole list. The free Two Factor plugin maintained by the core team, or the 2FA module in Wordfence or Solid Security, all work. TOTP (authenticator app) is plenty; you do not need hardware keys for a typical site.
- Rate-limit and lock out. Wordfence, Solid Security, and most security plugins cap failed attempts per IP — five failures in a short window is a sane threshold. This is what neutralizes brute force regardless of password strength.
- Watch your Application Passwords. Since WordPress 5.6, every user can mint Application Passwords for the REST API, and these bypass two-factor by design. They are useful, but each one is a standing credential. Audit Users → Profile → Application Passwords, revoke anything you do not recognize, and if you do not use them at all, disable the feature with the
wp_is_application_passwords_available filter.
2. Vulnerable code (the number-one real-world vector)
If a WordPress site you own gets hacked, the odds strongly favor an unpatched plugin or theme as the entry point — not a clever zero-day, but a published CVE that you simply had not patched yet. The fix is unglamorous: update discipline plus a smaller footprint.
- Enable auto-updates for plugins and themes on anything that is well-maintained, and check the dashboard weekly for the ones you would rather review by hand. WordPress core minor releases already auto-update; do not disable that.
- Shrink the attack surface. Every inactive plugin and theme still ships exploitable PHP to your server. Delete — do not just deactivate — anything you are not using. Keep one default theme (such as Twenty Twenty-Five) as a fallback and remove the rest. Fewer components means fewer CVEs that can ever apply to you.
- Avoid abandoned plugins. A plugin with no update in over a year, or one that has been pulled from the repository, is a liability even if it currently works. Check the "last updated" date before you install anything, and replace plugins that go dark.
- Subscribe to vulnerability intelligence. Patchstack and the WPScan database both publish new WordPress vulnerabilities daily and will tell you when something you actually run is affected. Patchstack's free tier even offers virtual patching — a rule that blocks the exploit at the request level before the official plugin fix lands, which buys you time during that dangerous window between disclosure and patch.
3. Server and file hardening
These controls limit what an attacker can do after a foothold, and close off a few information-leak paths that automated recon relies on. A handful of lines in wp-config.php do most of the work.
- Block in-dashboard code editing:
define('DISALLOW_FILE_EDIT', true); stops a compromised admin session from rewriting your theme's PHP through Appearance → Theme File Editor. For a stricter posture on a site you deploy via Git or SFTP, define('DISALLOW_FILE_MODS', true); also blocks all plugin and theme installs and updates from the dashboard entirely — use it where updates happen through your pipeline, not the UI.
- Get file permissions right. Directories at
755, files at 644, and wp-config.php ideally tightened to 640 or 600. Anything set to 777 is a red flag and frequently a sign of either bad advice or an existing compromise.
- Disable XML-RPC if nothing uses it. In 2026 it is rarely needed — the legacy interface mainly serves old mobile apps and pingbacks, and it is a favorite for amplified brute-force (it lets attackers test many passwords per request). Most security plugins toggle it off; confirm nothing you rely on, like a Jetpack feature, breaks first.
- Stop REST user enumeration. By default,
/wp-json/wp/v2/users will list your authors' usernames to anyone, handing brute-force bots half of every credential. A security plugin can restrict this endpoint to authenticated requests, or you can filter rest_endpoints to remove it.
4. The edge: transport and the firewall question
Everything above happens inside WordPress. The edge is where you stop traffic before it reaches PHP.
- Enforce HTTPS everywhere and confirm both URLs in Settings → General use
https://. Then add an HSTS header (Strict-Transport-Security: max-age=31536000; includeSubDomains) so browsers refuse to downgrade to HTTP on future visits.
- Understand the WAF trade-off. A plugin firewall (Wordfence, Solid Security) is easy to enable, but it runs as a WordPress plugin — meaning PHP has already booted by the time it inspects the request. It cannot protect you from attacks that exhaust resources before WordPress loads, and it goes down if the site goes down. An edge WAF like Cloudflare filters at the network layer, before any request touches your server, and absorbs volumetric attacks a plugin cannot. If you run anything you care about, put a real WAF at the edge and treat the plugin firewall as a second layer, not the only one.
5. Assume breach: backups you have actually restored
The previous four sections reduce the odds of a compromise. This one decides whether a compromise is an annoyance or a catastrophe. Hardening fails sometimes; recovery is what saves you.
- Automate off-site backups. UpdraftPlus or BlogVault, running at least daily, writing to storage that is not the same server as the site — S3, Google Drive, Dropbox. A backup sitting on a hacked host is a backup the attacker can delete or poison.
- Test the restore before you need it. This is the step everyone skips and the one that matters most. Restore a backup to a staging site and confirm it actually comes back clean. The morning you discover your backups have been silently failing for three months should not be the morning you are also cleaning up an intrusion.
- Rotate your salts after any incident. If you even suspect a session was hijacked, generate fresh keys from the WordPress salt generator and paste them into
wp-config.php. This invalidates every existing login cookie instantly and forces everyone — including the attacker — to re-authenticate.
The condensed version
If you do nothing else: turn on two-factor for admins, enable a login lockout, and keep plugins updated while deleting the ones you do not use. Those three close off the vectors that account for most real-world WordPress hacks. The server hardening, edge WAF, and tested backups turn a survivable mistake into a non-event. Work top to bottom, and stop treating a 30-second toggle as if it carried the same weight as the controls that actually keep you out of trouble.