Most compromised WordPress sites are not beaten by clever attacks on WordPress core: they fall to an outdated plugin, a reused administrator password, a forgotten FTP account or a backup that was never tested. This checklist turns the WordPress project's own hardening and brute force guidance into a set of numbered checks a site owner, agency or hosting team can work through and sign off. It covers updates, plugins and themes, administrator accounts, wp-config.php and file permissions, hosting and database access, DNS and domain control, firewall and rate limiting, backups, and monitoring. Use it for a new site before launch, as a quarterly review, or as the acceptance checklist when you take over a site from someone else. For the PHP runtime, secrets in wp-config.php and Composer-managed builds in more depth, see the PHP and WordPress Security Guide.
How to use this template
- Replace text in square brackets, such as [Site name], [Site owner] and [Hosting provider], with your own details. Keep one completed copy per site.
- Each check has an ID (for example 2.3) so you can record status, evidence and the date checked in a ticket, spreadsheet or audit file.
- "Must" marks a baseline item every site should meet; "should" marks a recommended item where a documented exception is acceptable, for example a site that genuinely needs XML-RPC for a mobile app.
- Work through sections 1 to 4 first: they close the most common ways in. Sections 5 to 9 reduce the impact when something does go wrong.
- Repeat the review at least every [quarter], after any change of developer, agency or host, and after any security incident.
| Field | Record |
|---|---|
| Site and URL | [Site name], [https://example.org] |
| Site owner (accountable) | [Name, role] |
| Technical maintainer | [Person or agency, contact] |
| Hosting provider and plan | [Hosting provider], [shared, managed WordPress, VPS or cloud] |
| Domain registrar and DNS provider | [Registrar], [DNS provider] |
| Date of review and reviewer | [Date], [Name] |
1. Inventory and ownership
- 1.1 The site must have a named owner and a named technical maintainer, recorded above.
- 1.2 Record every place a credential for the site exists: WordPress users, hosting control panel, SFTP or SSH accounts, database users, registrar, DNS provider, CDN or WAF dashboard, backup service, and any remote management dashboard connected to the site.
- 1.3 List every installed plugin and theme with its version, source (WordPress.org directory, a named commercial vendor, or custom code) and the business reason it is needed.
- 1.4 Confirm the site runs a WordPress version still receiving security releases and a PHP version still supported by the PHP project. The Site Health screen (Tools, Site Health) shows both and flags outdated components.
2. Updates
WordPress has offered automatic background updates since version 3.7. The WordPress upgrade documentation says minor core releases (maintenance and security releases) update automatically by default, major releases auto-update by default only on fresh installs made on WordPress 5.6 or later, and plugins and themes update automatically only when you turn it on or in special cases where WordPress.org flags a critical security fix.
- 2.1 Minor core updates must stay enabled. Do not set
AUTOMATIC_UPDATER_DISABLED; the WordPress documentation discourages it because minor updates keep sites secure. - 2.2 Decide the policy for major core updates and record it.
define( 'WP_AUTO_UPDATE_CORE', 'minor' );in wp-config.php allows minor updates only;trueallows minor and major. The constant overrides the setting on the Updates screen. - 2.3 Turn on auto-updates for plugins and themes from the Plugins and Themes screens, at least for low-risk plugins. Where a plugin is business-critical and auto-update is off, someone must check for and apply updates within [7] days, and within [48 hours] for a security release.
- 2.4 Back up the files and database before a major update, as the upgrade documentation advises, and test major updates on a staging copy first where one exists.
- 2.5 Download WordPress itself only from wordpress.org.
3. Plugins and themes
- 3.1 Delete, do not just deactivate, every plugin and theme that is not in use. Deactivated code is still on disk and can still be reached if it has a flaw. Keep one default theme as a fallback.
- 3.2 Install plugins and themes only from the WordPress.org directory or well-known vendors, as the WordPress hardening page advises. Never install "nulled" (pirated) copies of paid plugins.
- 3.3 Before adding a plugin, check when it was last updated, whether it is still maintained and whether the vendor publishes a way to report vulnerabilities. Prefer one well-maintained plugin over several overlapping ones.
- 3.4 Avoid plugins that run arbitrary PHP stored in the database (snippet or code-execution plugins). The hardening page recommends custom page templates instead.
- 3.5 Subscribe to a vulnerability feed or use a scanning service that matches your installed plugin versions against published WordPress vulnerabilities, and act on matches under section 2.3.
- 3.6 Treat remote management and backup plugins as privileged: they hold keys that can push code to the site. Disconnect any dashboard you no longer use and revoke its keys. The UpdraftCentral key theft in October 2026 showed how stolen connection keys let an attacker send validly signed commands that installed backdoor plugins.
4. Administrator accounts and login
| Default role | What it can do | Who should have it |
|---|---|---|
| Administrator | All administration features on a single site, including installing plugins and editing users | [Two] named people at most |
| Editor | Publishes and manages all posts, including other users' posts | Content leads |
| Author | Publishes and manages own posts | Regular writers |
| Contributor | Writes own posts but cannot publish them | Guest writers |
| Subscriber | Manages own profile only | Registered readers or customers |
| Super Admin | Network administration on Multisite | Multisite network operators only |
- 4.1 Every person must have their own account. No shared logins, and no account named
adminorwebmaster; the WordPress brute force guidance recommends creating a separate administrator account and demoting or deleting legacy ones. - 4.2 Keep the number of administrators to a minimum and give day-to-day work the lowest role that does the job, using the table above.
- 4.3 All administrators must use two-factor authentication. WordPress core does not include it, so add it with a plugin or by signing in through an identity provider. Passkeys (WebAuthn) give phishing-resistant login; register at least two authenticators per administrator so a lost device does not lock them out.
- 4.4 Passwords must be long and unique and kept in a password manager. See the Password Managers Explained for Everyone Guide.
- 4.5 Integrations that call the REST API must use Application Passwords (Users, Profile), one per integration, named after the system that uses it, so each can be revoked without changing the user's login password. Review and revoke unused Application Passwords at every review.
- 4.6 Remove accounts on the day a person or agency leaves, and reassign their content rather than keeping the account.
- 4.7 The admin area and login page must be served only over HTTPS.
5. Configuration and files
- 5.1 Add
define( 'DISALLOW_FILE_EDIT', true );to wp-config.php. This removes the built-in theme and plugin editors (theedit_themes,edit_pluginsandedit_filescapabilities), so a stolen administrator session cannot edit PHP from the dashboard. It does not stop uploads, so it is one layer, not a fix. - 5.2 Set file permissions as the hardening page recommends: directories 755 and files 644; wp-config.php 400 or 440 where the host supports it; the WordPress root,
wp-admin/,wp-includes/andwp-content/plugins/writable only by your user account;wp-content/writable by the web server because it holds uploads. - 5.3 Deny web access to wp-config.php. On Apache, a
<Files "wp-config.php"> Require all denied </Files>block at the top of .htaccess does this; the file can also sit one directory above the WordPress root. - 5.4 Block direct access to include-only scripts in
wp-includes/using the rewrite rules on the hardening page, placed outside the# BEGIN WordPressand# END WordPressmarkers so WordPress does not overwrite them. - 5.5 Generate unique authentication keys and salts in wp-config.php, and replace them after any suspected compromise; this signs out every logged-in session.
- 5.6 Never keep copies of wp-config.php, database dumps or backup archives inside the web root, where anyone who guesses the file name can download them.
6. Hosting, database and domain
- 6.1 Use SFTP or SSH, never plain FTP. Remove FTP accounts that are no longer used, and give each developer their own access.
- 6.2 Protect the hosting control panel, registrar, DNS provider and CDN accounts with two-factor authentication. Whoever controls DNS controls the site and its email, whatever the WordPress settings say. Turn on registrar lock where offered. See the DNS Security Guide.
- 6.3 Each site should have its own database and its own database user. For routine operation that user needs only SELECT, INSERT, UPDATE and DELETE, but the WordPress hardening page warns that updates and some plugins need schema changes, so if you remove other privileges, restore them temporarily for updates and keep tested backups.
- 6.4 Disable remote TCP connections to MySQL unless something genuinely needs them.
- 6.5 Ask the host how sites are isolated from each other on shared plans, whether PHP runs as a separate user per site, and how quickly it applies server security updates. The GoDaddy Managed WordPress breach showed that a host's own provisioning system can expose administrator passwords, sFTP and database credentials, so be ready to rotate all of them if your host reports an incident.
7. Firewall and brute force protection
| Layer | Example | Strength | Limitation |
|---|---|---|---|
| Edge WAF or CDN | Reverse-proxy service or host-provided WAF | Blocks and rate-limits before traffic reaches the server | Can be bypassed if the origin server's address is reachable directly |
| Server WAF | ModSecurity, Fail2ban | Runs before PHP, cheap under load | Needs server access, usually VPS or dedicated hosting |
| Security plugin | Login throttling, firewall rules inside WordPress | Works on any host, easy to configure | Runs inside PHP, uses more resources under heavy attack |
| Web server rules | IP allow list or HTTP Basic Auth on wp-login.php or /wp-admin/ | Very strong for sites with few, fixed editors | Can break admin-ajax.php and front-end features if scoped too widely |
- 7.1 Put at least one firewall layer from the table in front of the site. The WordPress hardening page lists host-level plugins, server WAFs such as ModSecurity, and reverse-proxy services as options.
- 7.2 Rate-limit
/wp-login.phpand/xmlrpc.php. The WordPress brute force page gives an Nginx example of 10 requests per minute per IP with a burst of 20. - 7.3 Disable XML-RPC if nothing uses it. It is a frequent brute force target through the
system.multicallmethod. If you need it, for example for a mobile app or a connected service, restrict and rate-limit it. - 7.4 Where editors work from fixed addresses, restrict wp-login.php by IP; otherwise consider HTTP Basic Auth or a challenge on the login form. Test admin-ajax.php afterwards.
- 7.5 Do not rely on hiding the login URL. It reduces noise but is not a control.
8. Backups and recovery
- 8.1 Back up both files and the database on a schedule matched to how often content changes: [daily] for active sites.
- 8.2 Keep multiple generations, as the hardening page advises, so a clean copy from before an unnoticed compromise still exists. Keep at least one copy off the hosting account, with credentials the web server cannot use to delete it.
- 8.3 Encrypt backups and record checksums so you can show a copy has not changed.
- 8.4 Test a full restore to a staging location at least [twice a year] and record how long it took. See the Backup Security and Immutable Backup Guide.
9. Monitoring and incident response
- 9.1 Keep web server access and error logs for at least [90] days. WordPress's hardening page notes logs show IP addresses, timestamps and attempted actions such as cross-site scripting, file inclusion, directory traversal and brute force.
- 9.2 Monitor file integrity for executable types such as .php, using a tool such as OSSEC, Git or a scanning service, and alert on new PHP files in
wp-content/uploads/or new plugins nobody installed. - 9.3 Alert on new administrator accounts, failed login spikes and changes to the site's email address or user roles.
- 9.4 Use external uptime and integrity monitoring to catch defacement or injected spam that is only shown to search engines or visitors.
- 9.5 If you suspect compromise: take a copy of files, database and logs first; restore from a known-clean backup; reinstall core, plugins and themes from official sources; reset every credential in section 1.2, replace salts (5.5) and revoke Application Passwords and remote management keys; then find and fix the original entry point. See the Small Business Incident Response Guide.
10. Review and sign-off
| Metric | Target |
|---|---|
| Plugins and themes with an available update older than [7] days | 0 |
| Installed but inactive plugins and themes (excluding one fallback theme) | 0 |
| Administrators without two-factor authentication | 0 |
| Number of Administrator accounts | [2] or fewer |
| Days since last successful test restore | [180] or fewer |
| Unused Application Passwords and remote management connections | 0 |
Reviewed by [Name] on [Date]. Exceptions agreed by [Site owner]: [list each exception, the reason and the review date].
Implementation guidance
- Start with access (week 1): complete the credential inventory (1.2), remove old accounts, turn on two-factor authentication for every administrator, the hosting panel, registrar and DNS, and replace FTP with SFTP. These close the commonest ways in.
- Clean up code (week 1 to 2): delete unused plugins and themes, update everything, and turn on auto-updates for the rest. Take a backup before you start.
- Harden configuration (week 2): apply section 5 on a staging copy first. File permission and .htaccess changes can break uploads or plugins; if they do, revert the single change and test again rather than undoing everything.
- Add the firewall and rate limits (week 3): run new WAF or plugin rules in a monitoring or log-only mode where the tool offers one, then block. Check the contact forms, checkout, admin-ajax.php and any mobile app still work.
- Prove recovery (week 4): perform and time a restore, and write down who does what if the site is hacked.
- Keep it going: repeat the review each [quarter]. Small sites run by one person can meet the baseline with managed hosting, a security plugin and an off-site backup service; agencies running many sites should standardise this checklist across clients and track the section 10 metrics centrally.
This checklist maps to the protective and recovery functions of the NIST Cybersecurity Framework 2.0, and to the outdated-component and authentication risks in the OWASP Top 10.
Standards and references
- WordPress Developer Resources: Hardening WordPress
- WordPress Developer Resources: Brute Force Attacks
- WordPress Developer Resources: Upgrading WordPress
- WordPress.org Documentation: Roles and Capabilities
- NIST: Cybersecurity Framework 2.0
- OWASP: Top 10 Web Application Security Risks
This template is provided for guidance and must be adapted to your site and hosting. Related NHI Mgmt Group resources: PHP and WordPress Security Guide · Cloudflare Security Configuration Guide · Small Business Cybersecurity Basics Guide · DNS Security Guide