OneWebDesk

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 literally admin, 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.

#CheckWhy it mattersHow to do it
1Update core, plugins, themesUnpatched vulnerabilities are the #1 breach causeEnable minor auto-updates; review and apply plugin updates weekly
2Delete unused plugins and themesDeactivated code still sits on disk as attack surfaceDelete, don't just deactivate; keep one default theme
3Harden the admin accountadmin username + reused password = credential-stuffing baitCreate a new admin with a different username, delete the old one; 20+ char unique password
4Two-factor authentication (2FA)Blocks login even when the password leaksTOTP-app based 2FA plugin, mandatory for every administrator
5Limit login attemptsKills brute force after a handful of guessesLockout plugin (e.g. 5 failures) or server-level fail2ban
6Disable xmlrpc.php if unusedAllows hundreds of password guesses in a single requestBlock it at the web server unless Jetpack or remote publishing needs it
7Disable the file editorA stolen admin session can plant a webshell from the dashboardAdd DISALLOW_FILE_EDIT to wp-config.php
8Fix file permissionsLoose permissions (777) invite neighboring processes inFiles 644, directories 755, wp-config.php at 600640
9Daily off-site backupsBackups are the last line of defense; on-server copies get infected tooDB + files daily to somewhere off the server; test restores
10Security headers at the serverBrowser-level defense against clickjacking, XSS, MIME sniffingAdd 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.

  1. 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.
  2. Manage the salts: the eight keys from AUTH_KEY through NONCE_SALT sign 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 at api.wordpress.org/secret-key/1.1/salt/.
  3. Tighten its permissions: only the web server user ever needs to read this file, so set it to 600 (or 640 if 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.

  1. Invalidate every session and credential: regenerate all eight salts in wp-config.php to kill every login cookie, then rotate all admin passwords, the database password, FTP/SFTP and hosting-panel credentials.
  2. Remove unknown administrators: check the user list for admin accounts you never created. Planting a spare admin is the standard re-entry trick.
  3. Scan for and remove webshells: look for recently modified PHP files (find . -name "*.php" -mtime -14), any PHP inside wp-content/uploads, and eval(base64_decode(...)) patterns. PHP living in the uploads folder is a red flag by itself.
  4. 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.
  5. 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.
  6. 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?
No. A security plugin automates parts of the job — login limiting, malware scanning — but it cannot fix the #1 cause of breaches (outdated plugins left unpatched), weak reused passwords, or loose file permissions. Cover the ten basics first, then add a plugin on top as a helper, not a substitute.
How do I know if it is safe to disable xmlrpc.php?
Jetpack, some older mobile-app integrations, and certain remote-publishing tools use xmlrpc.php. If you use none of those, blocking it has no effect on normal site operation. Block it, watch for a few days, and if something breaks you can allow only the specific IPs that need it.
After a hack, is changing passwords enough?
Not on its own. If the attacker already planted a webshell or a hidden admin account, they walk right back in regardless of new passwords. You must also regenerate the wp-config salts to kill all sessions, scan for and remove malicious files, delete unknown admins, and update everything — in that order.
Why should wp-config.php be 600 instead of 644?
The file contains your database password and auth keys in plain text. With 644, other users on the same machine can read it — which on shared hosting means a compromised neighboring account can steal your database credentials. Restricting it to 600 (or 640 when group read is required) closes that path.
Can I keep backups on the same server?
No. In a full-site compromise or ransomware-style attack, backups stored on the server are encrypted, deleted, or infected along with everything else. Real backups live off the server — object storage, another machine, or a local download — and are restore-tested regularly.
Do deactivated plugins really pose a risk?
Yes. Deactivation only stops WordPress from loading the plugin; the PHP files remain on disk and some vulnerabilities are exploitable by requesting those files directly. Anything you are not actively using should be deleted, not just switched off.

Tools to use with this guide

Related guides