Free guide

The WordPress hardening guide.

Ten practical steps to lock down a WordPress site, in the order an attacker would try to break in. Distilled from twelve years of cleaning hacked sites — no theory, no padding.

10 steps · 20 min to read · Updated Apr 2026
Step 01 Critical

Patch everything, weekly.

The single most common vector we see is an unpatched plugin with a public CVE. Most "hacks" are not zero-days — they're 90-day-olds.

  • Enable automatic minor updates for WordPress core in wp-config.php.
  • Run plugin and theme updates weekly. Test on staging if you have it; ship anyway if you don't.
  • Remove any plugin you haven't used in 60 days. Inactive plugins can still be exploited.

Why this matters: 78% of the compromised sites we cleaned in 2025 had a known, patched CVE in an outdated plugin. Patching is the highest-ROI security work you can do.

Step 02 Critical

Secure wp-config.php.

Your wp-config.php holds database credentials and salts. Treat it like a secret.

# 1. Move it one directory above the web root if you can
# 2. Set permissions tight
chmod 440 wp-config.php

# 3. Add to wp-config.php (above "stop editing" line)
define('DISALLOW_FILE_EDIT', true);
define('WP_AUTO_UPDATE_CORE', 'minor');
define('FORCE_SSL_ADMIN', true);

Regenerate the eight unique keys in wp-config.php using the official WordPress salt generator. Rotate them every 6 months, or immediately after any suspicious activity.

Why this matters: A leaked wp-config.php is a full site takeover. We've seen it exposed via misconfigured backups, public Git repos, and verbose error pages.

Step 03 Critical

Force strong passwords and 2FA on every admin.

Brute force still works. In Q1 2026, we logged a median of 1,200 login attempts per day on small business sites. Don't make it easy.

  • Require 16+ character passwords for any user with editor or higher privileges.
  • Mandate TOTP-based 2FA for administrators — not SMS.
  • Audit your user list quarterly. Delete or downgrade abandoned accounts.

Why this matters: A single admin with the password "Summer2024!" cancels out every other security control on this list.

Step 04 High

Disable XML-RPC unless you need it.

The xmlrpc.php endpoint allows password testing at thousands of attempts per HTTP request, and most fail2ban rules miss it.

# nginx
location = /xmlrpc.php { deny all; access_log off; return 444; }

If you genuinely use XML-RPC (Jetpack, the WordPress mobile app, some legacy clients), restrict it to known IP addresses instead of leaving it world-readable.

Step 05 High

Disable in-dashboard file editing.

The "Edit Theme" and "Edit Plugin" screens let any compromised admin account drop a webshell in seconds. Turn them off.

define('DISALLOW_FILE_EDIT', true);
define('DISALLOW_FILE_MODS', true); // also blocks plugin install/update via dashboard

Use SFTP or your deploy pipeline for legitimate file changes. The friction is the point.

Step 06 High

Lock down file permissions.

WordPress should never be able to write to its own core files in production.

  • Directories: 755
  • Files: 644
  • wp-config.php: 440 (owner+group read only)
  • .htaccess: 644 with extra care — many compromises start here

Make the web user (usually www-data) the group, not the owner. The owner should be your deploy user.

Step 07 Medium

Add security headers.

Free, easy, surprisingly often skipped. Add these in nginx, Apache, or via a header plugin if you have no server access.

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;

A Content-Security-Policy header is more effective but requires testing — we cover it in a separate post on the blog.

Step 08 Medium

Limit login attempts.

Rate-limit /wp-login.php at the web server, not just at the application layer. By the time WordPress sees the request, it has already done a database lookup.

# nginx
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
location = /wp-login.php { limit_req zone=login burst=3 nodelay; }

Five attempts per minute per IP is plenty for a real human. Bots will hit the wall.

Step 09 Medium

Harden the database.

  • Change the default wp_ table prefix on new installs.
  • Use a dedicated database user with privileges scoped to the WordPress database only.
  • Never run MySQL on a public IP. Bind to localhost or use a private network.

Changing the table prefix on an existing site is risky — only do it on a fresh install or a fully tested staging clone.

Step 10 Critical

Set up off-site, encrypted, tested backups.

This is the step that turns "we got hacked" into "we restored in 20 minutes." Three rules:

  • Off-site: a backup on the same server is not a backup. Use S3, B2, or any object storage in a different region.
  • Encrypted: with a key you control, not the backup plugin's hosted service.
  • Tested: restore to a staging environment quarterly. Untested backups fail at the worst possible moment.

Why this matters: Of the sites we couldn't fully recover in 2025, 100% had backup systems that the owner believed were working but had silently broken months earlier.

Quick-print checklist

If you only do these ten things, you'll be ahead of 95% of WordPress sites on the public internet.

  1. Plugins, themes, and core updated this week
  2. wp-config.php moved or chmod 440
  3. Salts regenerated in the last 6 months
  4. Strong passwords + TOTP 2FA on all admins
  5. Inactive admin accounts removed
  6. XML-RPC disabled or IP-restricted
  7. DISALLOW_FILE_EDIT = true
  8. File permissions: 755 / 644 / 440
  9. HSTS + nosniff + frame-options + referrer-policy headers set
  10. Login endpoint rate-limited at web server
  11. Dedicated, scoped database user
  12. MySQL not exposed publicly
  13. Off-site backups, encrypted, restore-tested in last 90 days

Want this audited automatically?

SecureAuditWP runs every check on this page (and 60 more) on a schedule, and writes you a PDF report.