All posts
March 12, 2026·6 min read·Long Nguyen · CTO, ERPFit·Updated June 17, 2026
wordpresssecuritychecklist
WordPress Security: A 9-Step Hardening Checklist

WordPress Security: A 9-Step Hardening Checklist

A 9-step WordPress security checklist: fix file permissions, block XML-RPC, enable 2FA, set HTTP headers, run offsite backups. From dozens of real hacked sites.

Table of Contents

WordPress powers around 43% of all websites (W3Techs, 2026). That also makes it the most common target. We've cleaned up many hacked WordPress sites — malware injected into core files, redirects to phishing pages, backdoors hidden in plugins. This post shares the security checklist we apply to every client website.

This isn't theory. Every item in this checklist originated from a real incident we encountered and resolved. Most real-world breaches don't hit WordPress core itself but plugins and themes — exactly the vulnerable third-party components OWASP Top 10 keeps warning about.

1. File Permissions

Incorrect file permissions are the most common reason malware can write files to the server. WordPress standards:

  • Directories: 755 (owner read/write/execute, group and others read/execute only)
  • Files: 644 (owner read/write, group and others read only)
  • wp-config.php: 600 or 640 — this file contains database credentials, nobody besides the owner needs to read it

Many shared hosting providers set permissions to 777 for the uploads directory — anyone on the server can write files there. This is inviting hackers in.

# Fix permissions for entire WordPress installation
find /path/to/wordpress -type d -exec chmod 755 {} \;
find /path/to/wordpress -type f -exec chmod 644 {} \;
chmod 600 /path/to/wordpress/wp-config.php

2. Login Protection

Brute force is the simplest attack method — bots try thousands of username/password combinations. Countermeasures:

  • Limit failed login attempts. Limit Login Attempts Reloaded plugin — free, effective. After 3 failures, lock IP for 15 minutes. After 3 lockouts, lock for 24 hours.
  • Don't use "admin" as username. Bots always try "admin" first. Create hard-to-guess usernames.
  • Change login URL. Default is /wp-login.php and /wp-admin/. Change to a custom URL. Not bulletproof security — but eliminates 90% of bots.
  • Two-factor authentication. For admin accounts, 2FA should be mandatory. WP 2FA plugin works well.

3. Disable XML-RPC

XML-RPC (/xmlrpc.php) is WordPress's legacy API — allows posting from external applications. Most sites don't need it, but it's open by default. The problem: XML-RPC allows trying multiple passwords in one request (system.multicall) — bypassing login rate limits.

# In .htaccess (Apache)
<Files xmlrpc.php>
  Require all denied
</Files>

Or in Nginx:

location = /xmlrpc.php {
  deny all;
  return 403;
}

If you need XML-RPC (e.g., for Jetpack), whitelist specific IPs instead of opening it to everyone.

4. HTTP Security Headers

Headers don't prevent server-side malware — but they protect users from client-side attacks (XSS, clickjacking, MIME sniffing):

# Add to .htaccess or nginx config
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()

Content-Security-Policy (CSP) is the most effective but also most complex — easy to break things if misconfigured. We add CSP gradually, testing thoroughly before enforcing.

5. Disable File Editing in Admin

WordPress by default allows editing plugin and theme files from the admin panel. If an admin account is compromised, hackers can inject malware directly from the web interface.

// Add to wp-config.php
define('DISALLOW_FILE_EDIT', true);
define('DISALLOW_FILE_MODS', true); // Also disables plugin/theme install from admin

DISALLOW_FILE_MODS also disables plugin/theme updates from admin — you'll need to update via WP-CLI or SFTP. This is a safe trade-off: less convenient, but significantly more secure.

6. Database Security

  • Change table prefix. Default is wp_. Change to a random prefix to make SQL injection attacks harder (not impossible, but adds a layer).
  • Dedicated database user for WordPress. Don't use root. The user should only have SELECT, INSERT, UPDATE, DELETE permissions on the WordPress database — no DROP, ALTER, GRANT.
  • Remove unused tables. Old plugins leave orphan tables in the database. Clean up periodically.

7. Plugin and Theme Hygiene

Outdated plugins and themes are the most common attack vector. Rules:

  • Delete unused plugins — don't just deactivate. Inactive plugins can still be exploited if they have vulnerabilities.
  • Delete unused default themes. Keep the active theme + one default theme (Twenty Twenty-Four) for fallback.
  • Never use nulled/cracked plugins. 100% contain malware. No exceptions.
  • Vet plugins before installing. Check last update date, number of active installs, rating. Plugins not updated in >1 year = risk.
  • Auto-update minor versions. WordPress minor updates (5.9.1 → 5.9.2) are mainly security patches. Enable auto-updates.

8. Backup — The Last Line of Defense

Every security measure can be bypassed. Backup is the only thing that lets you recover when everything else fails.

  • Daily backups — both files and database
  • Store offsite — not just on the same server. If the server is compromised, backups on it are too.
  • Keep 30 days — sometimes malware is only discovered weeks later. You need clean backups from before infection.
  • Test restores — backups are meaningless if they can't be restored. Test at least quarterly.

Backups only help if you catch trouble early. An uptime monitoring setup like the one in our Uptime Kuma guide alerts you the moment a site goes down or starts redirecting strangely — an early sign of a hack.

9. Speed Optimization — Indirect Security

A slow website is often a sign of security issues — malware injecting code, abnormal database queries, or simply weak hosting that can't run security plugins.

  • Page caching — reduces PHP processing load. WP Super Cache or W3 Total Cache.
  • Object caching — Redis or Memcached for database query caching.
  • CDNCloudflare free tier reduces server load and adds basic WAF. Free SSL via Let's Encrypt should be the default for every site.
  • Image optimization — uncompressed images account for 50-80% of page weight. WebP conversion + lazy loading. For fast batch compression and format conversion, ERPFit's Craft tools handle it in bulk.
  • PHP version — PHP 8.2+ is significantly faster than 7.4. Upgrading PHP is the quickest optimization.

When the Site Is Already Hacked

If the site is already infected with malware, the checklist above isn't enough. Recovery process:

  1. Isolate — take the site offline or into maintenance mode immediately. Prevent malware from spreading and protect users.
  2. Scan entire filesystem — find abnormal files, recently created files, obfuscated code. wp-cli has wp core verify-checksums to compare core files against originals.
  3. Reinstall WordPress corewp core download --force. Keep wp-content/ and database.
  4. Check every plugin and theme — compare against originals from WordPress.org. Any modified file = suspicious.
  5. Check database — look for JavaScript/iframe injection in posts, options, user metadata.
  6. Change all credentials — admin passwords, database password, SFTP, hosting panel.
  7. Apply security checklist — all items above.
  8. Resubmit to Google Search Console — request removal of "This site may be hacked" warning.

The entire process takes 2-4 hours for a simple site, 1-2 days for complex ones. But more important is preventing reinfection — that's why the security checklist must be applied immediately after cleanup.

Conclusion

WordPress security isn't hard — but it requires discipline. Most sites get hacked not because hackers are skilled, but because site owners forgot to update plugins, used weak passwords, or installed cracked themes.

This checklist isn't invulnerable. But it eliminates the vast majority of common attack vectors — and that's the difference between a secure site and one that will be hacked within the next 6 months. If you're building infrastructure from scratch, see the open-source stack we use for clients.

Frequently asked questions

How do I know if my WordPress site is hacked?
Common signs: redirects to unknown pages, a "This site may be hacked" warning in Google, strange new files in directories, or admins unable to log in. Run wp core verify-checksums to compare core against the originals from WordPress.org, and scan with a plugin like Wordfence.
Is XML-RPC safe to leave enabled?
XML-RPC (/xmlrpc.php) is open by default and a common brute-force vector because it allows trying many passwords in a single request. Most sites don't need it. Unless you use Jetpack or an external posting app, block it entirely via .htaccess or Nginx as shown above.
Which security plugins does WordPress really need?
At minimum: a login limiter (Limit Login Attempts Reloaded), 2FA (WP 2FA), and a malware scanner (Wordfence or Sucuri). Avoid stacking too many overlapping security plugins — they conflict and slow the site more than they protect it.
Should I enable auto-updates for WordPress?
Enable auto-updates for minor core versions and security patches, since these are mostly vulnerability fixes. Test major versions and critical plugins on staging first. Pair daily backups with uptime monitoring so you catch any update that breaks the site immediately.
Does changing the database table prefix actually stop hacks?
Changing the prefix from wp_ to a random string isn't absolute security — it only makes automated SQL injection scripts slightly harder. Treat it as an extra layer, not a replacement for updating plugins, using a least-privilege database user, and keeping solid backups.
LN
Long Nguyen
CTO, ERPFit

CTO at ERPFit. Hands-on builder of the technical infrastructure, the Craft tool suite, and the service platform for Vietnamese businesses.

Share:𝕏FBin