Most WordPress compromises don’t involve anything clever. They come from a plugin that stayed out of date, a login page nobody rate-limited, an admin account with a reused password, or a backup that turned out not to exist. Hardening is the unglamorous work of closing those doors before something walks through. This checklist is ordered by how much risk each step removes per minute spent, and for each item it says how to check the current state and where Loyal Security (free, from WordPress.org) does the work for you.
You don’t have to do all of it in one sitting. Steps 1–5 are the ones that matter most; do those today and the rest can follow over a week.
1. Get on top of updates — especially plugins and themes
Core is rarely the problem. The overwhelming majority of real-world WordPress compromises come in through third-party plugins and themes, usually through a vulnerability that already had a published fix. The gap between “fix released” and “your site updated” is the exposure window.
Check it:
wp core check-update
wp plugin list --update=available
wp theme list --update=available
Do it: enable automatic updates for plugins you trust and have tested, update the rest weekly, and delete anything inactive — a deactivated plugin’s files are still on disk and still reachable.
With Loyal Security: installed plugins and themes with known CVEs are flagged inline on the Plugins, Themes and Updates screens, so the “which update actually matters” question answers itself. For the gap while you test an update, virtual patching shields known-vulnerable third-party plugins and themes until you can apply the real fix.
2. Protect the login page
Every WordPress site receives automated login attempts, because /wp-login.php is at the same address on every default install. These are credential-stuffing runs using passwords leaked from other sites, not guesses. Two things stop them: making each attempt expensive, and making a stolen password insufficient.
Do it:
- Rate-limit login attempts per IP and lock out repeat offenders.
- Remove the default
adminusername and use unique, long passwords. - Check passwords against known breaches (see step 3).
With Loyal Security: rate limiting and brute-force protection are on by default, with a bad-bot blocker and optional login CAPTCHA (Cloudflare Turnstile or reCAPTCHA v3, only if you choose one and add your keys). More on the attack pattern in The Two URLs Every Attacker Tries First.
3. Turn on two-factor authentication for every admin
2FA is the cheapest high-impact control on this list. A leaked password alone stops working as soon as a second factor is required.
Do it: require 2FA for administrators and editors at minimum, and keep backup codes somewhere that isn’t the same device as the authenticator app.
With Loyal Security: TOTP with QR enrollment and backup codes, plus passkeys, a password policy, and breached-password checking. The breach check uses the Have I Been Pwned range API with k-anonymity — only the first five characters of the password’s SHA-1 hash leave your server, never the password, username or email — and it warns the user rather than blocking the login. Active-session management lets you end sessions you don’t recognise. From the command line: wp loyal-security twofa.
4. Put a web application firewall in front of PHP
A WAF inspects each request for known attack patterns — SQL injection, cross-site scripting, local and remote file inclusion, path traversal, remote code execution — and drops the ones that match before your code handles them. It is a safety net for the day a plugin you run turns out to have a hole.
With Loyal Security: the firewall runs in one of two modes. Optimized Mode loads before WordPress does, through a lightweight prepend, so a blocked request never boots WordPress at all. Standard Mode runs inside WordPress and needs no server-level change, which makes it the right choice on hosts where a prepend isn’t possible. Rules and signatures update from the threat-intelligence feed twice a day. The performance side of this choice has its own write-up: WordPress Security Plugins and Performance.
Behind a CDN or reverse proxy, tell the plugin which proxies to trust so it sees the real visitor IP — otherwise rate limits and blocks apply to the proxy’s address instead of the attacker’s.
5. Back up, and prove the backup restores
A backup is only a backup once you’ve restored from it. Keep copies off the server, keep several generations, and test a restore on a staging copy at least once.
With Loyal Security: on-demand and scheduled full-site backups (files and database), and a downloadable recovery tool you can upload to restore a backup even when WordPress itself won’t load — which is precisely the situation you’re in after a bad compromise. wp loyal-security backup makes it scriptable.
6. Lock down file and server configuration
Several defaults are convenient for development and unnecessary in production.
- Directory browsing off, so a missing
index.phpdoesn’t list a folder’s contents. - Sensitive files (
wp-config.php,.htaccess, backups, logs) not web-readable. - File editing from wp-admin disabled (
DISALLOW_FILE_EDIT) so a compromised admin account can’t edit plugin code in the browser. - Correct permissions: directories 755 and files 644 as a typical baseline,
wp-config.phptighter. - PHP execution blocked in
wp-content/uploads.
With Loyal Security: deep system hardening generates the .htaccess or Nginx rules, hardens wp-config.php, locks down directory browsing and obscures version information. Incident response includes a file-permission reset for when permissions have drifted.
7. Restrict the APIs you don’t use
XML-RPC and the REST API are legitimate features, and both are also attack surface. If you don’t use XML-RPC (most sites don’t), disabling it removes a favourite brute-force amplifier. For REST, you generally want to keep the public endpoints your front end needs and restrict anonymous access to the rest — notably user enumeration.
With Loyal Security: REST API and XML-RPC restriction are hardening toggles, so you can tighten them without writing filters. If you write your own endpoints, the common mistake is worth knowing: a permission_callback that always returns true.
8. Send browsers the right security headers
Headers cost nothing and cut off whole classes of attack: X-Content-Type-Options, X-Frame-Options (or frame-ancestors), Referrer-Policy, Permissions-Policy, HSTS once you’re certain everything serves over HTTPS, and a Content Security Policy for the strongest XSS mitigation.
A CSP is the one people avoid because it’s easy to break a site with a policy that’s too strict. With Loyal Security: the Content Security Policy manager builds a policy from the resources your site actually loads, and has a report-only mode so you can see what would be blocked before you enforce anything.
9. Watch file integrity
If an attacker gets a file onto your server, the earliest reliable sign is a file that shouldn’t be there or a file that changed. Core and plugin files from WordPress.org have published checksums you can verify:
wp core verify-checksums
wp plugin verify-checksums --all
Those commands can’t cover themes, mu-plugins, drop-ins or premium plugins, which is where backdoors like to hide.
With Loyal Security: file integrity monitoring verifies core and plugins against WordPress.org checksums and uses baseline diffing for everything else, including themes, mu-plugins and drop-ins. The malware scanner (heuristic regex plus token-based detection) runs on demand and automatically once a week. A separate database scanner looks where file scanners don’t: posts, page-builder content, comments, options, user meta and code-snippet plugins for injected scripts, spam links, a hijacked site address and rogue administrator accounts. When something is found, quarantine is safe and reversible, with one-click clean-file recovery.
10. Keep an audit trail
When something does go wrong, the first questions are always who changed what, and when? Without a log you’re guessing. Log logins (successes and failures), user and role changes, plugin and theme installs and activations, and settings changes — with IP and user.
With Loyal Security: a full audit log with IP, user and proxy tracking, 90-day default retention and CSV export, plus email alerts with plain-language guidance, throttling, quiet hours and per-event muting so the alerts that matter don’t get lost in noise. See Auditing WordPress Changes for what to log and why.
11. Review who has access
Hardening isn’t only technical. Every former contractor with an administrator account is an open door.
wp user list --role=administrator --fields=ID,user_login,user_email,user_registered
Remove accounts you don’t recognise, downgrade roles to the least privilege that works, and confirm that each remaining admin has 2FA. The database scanner’s rogue-administrator check catches accounts created behind your back.
12. Know your score, then re-check monthly
Security drifts: a new plugin, a changed setting, a lapsed backup schedule. The admin-bar Security Score gives an A–F grade at a glance, and wp loyal-security status prints the same health picture from the command line — good enough to drop into a cron job or a fleet-wide loop. The monthly routine that keeps it honest is in the 10-minute monthly security checklist.
The short version
- Update plugins/themes; delete the unused ones.
- Rate-limit logins; no
adminuser. - 2FA for every privileged account.
- WAF on, with the right mode and trusted proxies set.
- Backups off-server, restore tested.
- Directory browsing, file editing and uploads-PHP locked.
- XML-RPC off; REST user enumeration restricted.
- Security headers; CSP in report-only first.
- File integrity + malware + database scanning.
- Audit log with alerts.
- Audit administrators.
- Re-check monthly.
Everything above that names Loyal Security is in the free plugin on WordPress.org — nothing is locked or time-limited. The separate Pro plugin adds automation and agency tooling for people running many sites; see the Pro page if that’s you.
Loyal Security — Firewall & Malware Scanner
Free on WordPress.org: firewall, malware scanning and login protection in one plugin. Upgrade to Pro for threat intelligence, Sentinel and uptime monitoring.