← All posts

WordPress security hardening checklist

Most WordPress hardening advice is a long list of equally-weighted tips, which is unhelpful, because the items are not equally important. Hiding your login URL is near-worthless. Keeping plugins updated prevents most real compromises.

This is ordered by what actually stops attacks, with the theatre marked as such.

The four doors

Almost every compromised WordPress site was entered one of four ways:

  1. Outdated software with a publicly known vulnerability
  2. Nulled themes or plugins that shipped with a backdoor
  3. Weak or reused credentials
  4. Abandoned plugins that will never be patched
The four doors into a WordPress site Outdated software Weak / reused credentials Nulled themes / plugins Abandoned plugins WordPress the target
Close these four and you've addressed the overwhelming majority of real-world risk.

Close those four and you’ve addressed the overwhelming majority of real-world risk. Everything after is refinement.

Tier 1: do these today

Update everything, and automate it

Attackers scan for known vulnerabilities at scale. A disclosed plugin vulnerability is being probed within hours, and the fix already exists, you just haven’t applied it.

Enable auto-updates for at least security releases of core, and for plugins you trust. The risk of an update breaking something is real but far smaller than the risk of running known-vulnerable code for weeks.

Delete nulled anything

Pirated premium plugins and themes frequently contain backdoors. That’s the business model, not an accident. There is no trustworthy source for nulled software.

If a premium plugin isn’t in the budget, use a free alternative. A free plugin from the directory is vastly safer than a paid one from a warez site.

Strong unique passwords, plus 2FA on admins

Use a password manager. Enable two-factor for every administrator account. Credential stuffing works because people reuse passwords, and one breach elsewhere becomes a break-in here.

Remove what you don’t use

Every deactivated plugin and unused theme is still code on disk. Deactivated plugins can still be exploitable in some cases. Delete rather than deactivate.

Pay attention to plugins that vanished from the wordpress.org directory. Removal is often a security action, and nobody emails you about it.

Tier 2: worth doing this week

Disable file editing

define( 'DISALLOW_FILE_EDIT', true );

This one line means a stolen admin session can’t rewrite your theme from the browser. It converts “attacker got an admin login” from catastrophic to merely bad.

Block PHP execution in uploads

wp-content/uploads holds media. It should never execute code. Blocking PHP there neutralises the most common webshell placement, and costs nothing.

Turn debug output off in production

define( 'WP_DEBUG', false );
define( 'WP_DEBUG_DISPLAY', false );

Debug output leaks paths, queries, and versions to anyone who can trigger an error.

Don’t use admin as a username

Half of all brute-force attempts try admin first. Using anything else makes those attempts fail on the username, before the password even matters.

HTTPS everywhere

Not optional. Free via Let’s Encrypt on effectively every host.

Least-privilege user roles

Not everyone needs to be an administrator. Editors edit, authors write. This limits the blast radius when one account is compromised.

Tier 3: real, but secondary

Security headers

Content-Security-Policy, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, and Strict-Transport-Security. These reduce the impact of certain attacks rather than preventing entry.

Rate-limit or protect login

Slows brute force. Increasingly redundant if you have strong passwords and 2FA, but harmless.

Consider XML-RPC

Legitimately used by the mobile app and Jetpack. If you use neither, disabling it removes an attack surface used for amplified brute force.

Backups you have actually restored

An untested backup is a hope, not a plan. Restore one to a staging site once. Store copies off-server, because a compromised server can take its own backups with it.

Security theatre: skip these

Hiding the login URL. Moving /wp-admin stops opportunistic bots and nothing else. It’s mildly inconvenient for you and trivial for anyone actually targeting you. Not harmful, just not security.

Hiding the WordPress version. Version disclosure is a real finding in scans, but attackers overwhelmingly probe for the vulnerability rather than checking your version first. Fix the underlying outdated software instead.

Changing the database table prefix on an existing site. Meaningful only against certain blind SQL injection, and the migration risk on a live site usually outweighs it. Fine on a fresh install, not worth retrofitting.

Priority ladder — strongest at the top Tier 1 — today updates, delete nulled, 2FA, remove unused Tier 2 — this week file editing off, block PHP in uploads, HTTPS, roles Tier 3 — secondary security headers, login rate-limit, tested backups Security theatre — skip hide login URL, hide version, change table prefix
This is ordered by what actually stops attacks, not by what's easiest to write about.

Checking where you stand

Auditing this by hand is tedious, and the tedious parts are the ones people skip. If you have an AI agent connected through a WordPress MCP server, scan-security checks the hardening items above alongside core-file integrity, malware heuristics, and outdated or abandoned software, and returns a scored report with ranked recommendations.

You: Audit this site's security.
AI: scan-security({ checks: ["hardening", "software"] })
→ Score 72 (C)
• File editing enabled in wp-admin (warning)
• 3 plugins with pending updates (warning)
• 1 plugin removed from wordpress.org (critical)
• Version disclosed in generator meta (info)

It’s read-only, so it can’t break anything, and the ranking matters as much as the findings, since a checklist without priorities is how people spend an afternoon on headers while a vulnerable plugin sits there.

If you only do three things

  1. Turn on automatic updates.
  2. Delete every nulled plugin and theme, and everything you’re not using.
  3. Unique passwords plus 2FA on every admin.
If you only do three things 1 2 3 Auto-updates on Delete nulled + unused Unique passwords + 2FA
Three actions that close the doors real compromises actually come through.

That’s not a complete defence, but it closes the doors that actual compromises actually come through.

← All postsSubscribe via RSS