WordPress Security Basics: 10 Checks That Stop Most Hacks
The common ways WordPress gets hacked, and the login, plugin, file-permission and header settings that stop them.
WordPress powers over 40% of the web, which makes it the highest-return target for attackers. The important thing to understand is that almost nobody is attacking your site specifically. Attackers load one known vulnerability into a scanner, sweep the entire internet, and automatically infect whatever responds. “My site is too small to hack” is not a defense — bots never check how big a site is, only whether it is vulnerable.
The good news: real-world breaches happen through a handful of predictable doors, so ten basic checks stop the vast majority of automated attacks. This guide walks through how WordPress actually gets compromised, the ten essential checks — login, plugins, file permissions, server headers — and the exact recovery order if you have already been hacked.
How WordPress actually gets hacked
Incident statistics from security vendors are remarkably consistent year after year. In order of frequency:
- #1: Known vulnerabilities in outdated plugins and themes. By far the biggest cause. Once a vulnerability is disclosed, mass scanners start probing within hours, and every site that delayed the update gets swept up. Plugins are breached far more often than WordPress core itself.
- #2: Credential stuffing against
wp-login.php.Bots replay username/password pairs leaked from other sites' breaches. If you reused a password anywhere, or your username is literallyadmin, a takeover is only a matter of time. - #3: Nulled themes and plugins.“Free” copies of paid themes routinely ship with backdoors baked in — you install the compromise yourself. Never upload a zip from an untrusted source.
- #4: Cross-contamination on shared hosting. When a neighboring account on the same server gets breached, weak isolation lets the infection spread into your files. This is why account isolation and strict file permissions matter even if your own site is clean.
Notice the common thread: every route is automated. No human is studying your site — bots are pattern-matching for weaknesses, so covering the basics literally removes you from the target pool.
The 10 essential checks — what, why, how
This table is the core of the guide. Work top to bottom; most sites finish in about thirty minutes.
| # | Check | Why it matters | How to do it |
|---|---|---|---|
| 1 | Update core, plugins, themes | Unpatched vulnerabilities are the #1 breach cause | Enable minor auto-updates; review and apply plugin updates weekly |
| 2 | Delete unused plugins and themes | Deactivated code still sits on disk as attack surface | Delete, don't just deactivate; keep one default theme |
| 3 | Harden the admin account | admin username + reused password = credential-stuffing bait | Create a new admin with a different username, delete the old one; 20+ char unique password |
| 4 | Two-factor authentication (2FA) | Blocks login even when the password leaks | TOTP-app based 2FA plugin, mandatory for every administrator |
| 5 | Limit login attempts | Kills brute force after a handful of guesses | Lockout plugin (e.g. 5 failures) or server-level fail2ban |
| 6 | Disable xmlrpc.php if unused | Allows hundreds of password guesses in a single request | Block it at the web server unless Jetpack or remote publishing needs it |
| 7 | Disable the file editor | A stolen admin session can plant a webshell from the dashboard | Add DISALLOW_FILE_EDIT to wp-config.php |
| 8 | Fix file permissions | Loose permissions (777) invite neighboring processes in | Files 644, directories 755, wp-config.php at 600–640 |
| 9 | Daily off-site backups | Backups are the last line of defense; on-server copies get infected too | DB + files daily to somewhere off the server; test restores |
| 10 | Security headers at the server | Browser-level defense against clickjacking, XSS, MIME sniffing | Add HSTS, X-Frame-Options etc. in nginx/Apache, then verify |
For check #3, what matters is a long, uniquepassword — not eight “complex-looking” characters. If your site has multiple users, decide the rules you will enforce first; the password policy generator produces a ready-to-adopt policy for length, reuse and rotation. For check #10, headers belong at the server (nginx/Apache) rather than in a WordPress plugin, and after deploying them you can confirm what your site actually sends with the security headers checker.
Hardening wp-config.php — three changes
wp-config.php holds your database credentials and authentication keys, making it the single most sensitive file in the install. Three changes cover the essentials.
- Kill the file editor: one line,
define('DISALLOW_FILE_EDIT', true);, removes the theme/plugin editor from the dashboard. Even if an attacker hijacks an admin session, the easiest path to dropping a PHP webshell is gone. - Manage the salts: the eight keys from
AUTH_KEYthroughNONCE_SALTsign every login cookie. Replace them if they are still defaults or copied from another install, and always regenerate them after a suspected compromise — new salts instantly invalidate every session, including any stolen cookies. Use the official generator atapi.wordpress.org/secret-key/1.1/salt/. - Tighten its permissions: only the web server user ever needs to read this file, so set it to
600(or640if group read is required). On shared hosting this is the minimum barrier against a compromised neighboring account reading your database password.
Worked example: you have been hacked — triage in order
If spam pages or redirects are already live, the order of operations matters more than speed. Lock the doors before you clean — reverse the order and the attacker walks back in while you are still scrubbing.
- Invalidate every session and credential: regenerate all eight salts in
wp-config.phpto kill every login cookie, then rotate all admin passwords, the database password, FTP/SFTP and hosting-panel credentials. - Remove unknown administrators: check the user list for admin accounts you never created. Planting a spare admin is the standard re-entry trick.
- Scan for and remove webshells: look for recently modified PHP files (
find . -name "*.php" -mtime -14), any PHP insidewp-content/uploads, andeval(base64_decode(...))patterns. PHP living in the uploads folder is a red flag by itself. - Update or reinstall everything: overwrite core with a fresh official zip and reinstall plugins and themes from the repository. This closes the vulnerability that let the attacker in.
- Restore from a clean backup if needed: a pre-infection off-site backup is the most reliable cleanup of all. If you did check #9, this step takes minutes.
- Prevent the rerun: re-apply all ten checks from the top, and if Google Search Console flagged a security issue, submit a review request once the site is clean.
Turn it into a routine
Security is a habit, not a one-time setup. For a personal or small-business site, a weekly update pass, a monthly cleanup of users and plugins, and a quarterly restore test are enough. To see how many of the ten checks your site currently passes — and to track your progress item by item — run the WordPress hardening checklist, and use the security headers checker to verify what your server actually returns.
Frequently asked questions
Is installing one security plugin enough?
How do I know if it is safe to disable xmlrpc.php?
After a hack, is changing passwords enough?
Why should wp-config.php be 600 instead of 644?
Can I keep backups on the same server?
Do deactivated plugins really pose a risk?
Tools to use with this guide
Related guides
- Essential Security Headers Guide (CSP, HSTS, X-Frame-Options)The security headers you must set, what each does, recommended values and common mistakes.
- SSL Certificate Errors (NET::ERR_CERT…): Causes and FixesFive common causes of browser SSL errors and authorized=false, and how to fix each.