WordPress Security Best Practices for 2026
WordPress security as a system, not a checklist. Hardening, plugin hygiene, WAF, monitoring, and the secure-coding patterns that prevent the most common breaches.
WordPress runs roughly 43% of the web. That scale is what makes it the largest attack surface on the internet — not because the platform is poorly designed, but because there's simply more of it to attack. The defaults in modern WordPress are reasonable. The failure modes are concentrated in a small number of repeating patterns. This piece covers what we actually do for client sites — security as a system, not a checklist of plugins to install.
The threat landscape in 2026
Most WordPress breaches still trace back to a short list of root causes. Outdated plugins remain the single largest vector — the plugin you stopped updating two years ago because the author stopped releasing patches is the door an attacker walks through. Credential stuffing against /wp-login.phpis constant background noise. Supply-chain compromise — where a legitimate plugin's update mechanism is hijacked to push malicious code to thousands of sites at once — has gone from theoretical to regular. Abandoned plugins still installed and active. Exposed admin and REST API endpoints scraped by bots.
Three things are different in 2026. AI-assisted credential stuffing has made password attacks meaningfully more sophisticated — slower, more distributed, harder to rate-limit on simple counters. Supply-chain attacks targeting popular WP plugins have escalated; a compromised maintainer account can poison every site that auto-updates. And REST API enumeration via /wp-json/has become a default scanning behaviour, often the first thing a botnet checks before deciding whether your site is worth a deeper probe.
The hardening foundations most sites still get wrong
Before any plugin or scanner, a small set of foundations need to be in place. These are the items that separate sites that get breached from sites that don't.
- Strong unique admin credentials with MFA via app authenticator. Not SMS — SMS is vulnerable to SIM swapping and an authenticator app is no harder to use.
- Disable file editing in admin. Add
define('DISALLOW_FILE_EDIT', true);towp-config.php. A compromised admin should not translate to live PHP execution from the dashboard. - Hide
/wp-adminand/wp-login.phpfrom general traffic.Rate-limit them aggressively at the edge, gate them behind 2FA, and consider a per-IP allowlist for staff. Security-through-obscurity alone is weak; combined with proper rate-limiting it's a meaningful friction layer. - Disable XML-RPC unless you actively use it. Most modern sites don't. It's a brute-force target and a DoS amplifier.
- Lock down file permissions. 644 for files, 755 for directories, 600 for
wp-config.php. Anything more permissive on production is a misconfiguration. - Force HTTPS site-wide with HSTS.
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload. Submit to the HSTS preload list once you're sure.
The configuration snippet most worth knowing — at the top of your wp-config.php, before the "That's all, stop editing" line:
/* Disable in-dashboard file editing — attacker with admin
should not be able to drop a webshell from the UI. */
define( 'DISALLOW_FILE_EDIT', true );
define( 'DISALLOW_FILE_MODS', true );
/* Force SSL for the admin and login surfaces. */
define( 'FORCE_SSL_ADMIN', true );
/* Disable WP_DEBUG on production. WP_DEBUG_LOG to a file
that's not web-accessible if you need it for triage. */
define( 'WP_DEBUG', false );
Plugin and theme hygiene
Every plugin you install is a trust transfer — to the author, their development practices, their account security, and their ability to ship safe updates. Treat that transfer as the major decision it actually is.
- Only install plugins from reputable authors with active maintenance. The wordpress.org repository's "last updated" date and "tested with" version are real signals — anything more than a year stale is a yellow flag, more than two is a kill.
- Audit every plugin quarterly. Deactivated does not equal safe — files still on disk are still an attack surface. Remove what you're not using.
- Use a paid security scanner like Wordfence Pro, Patchstack, or Solid Security. These aren't replacements for hardening — they're alerting layers on top of it.
- Never edit core, the parent theme, or plugin files directly. Child themes and snippet plugins exist for a reason.
- Subscribe to a vulnerability feed (Wordfence, Patchstack, WPScan). Patch within 24 hours of a critical advisory; faster for sites with sensitive data.
Database and wp-config hardening
On new installs, change the default wp_table prefix. The value is low — it stops trivially-templated SQL injection attempts but a determined attacker discovers your prefix quickly. The cost is also low. Do it on new installs; don't break a working production site to add it later.
Move wp-config.php one directory above the web root if your hosting allows it. Regenerate the unique salts via api.wordpress.org/secret-key/1.1/salt/ on every fresh install and after any suspected compromise. Restrict the database user's privileges to what WordPress actually needs day-to-day — most sites can live without DROP and ALTER in normal operation, with a separate elevated user for migrations and updates.
For any custom code, use $wpdb->prepare() for every SQL query that touches user input. Never concatenate. The deeper context for safe data handling lives in our guide to WordPress hooks — most security work happens inside hook callbacks.
Authentication and access control
Two-factor authentication for every administrator and editor account, no exceptions. The exception you grant for "just this one account" is the account that gets compromised. Limit login attempts via Limit Login Attempts Reloaded or equivalent (some WAFs do this at the edge, which is better). Different roles for different jobs — Administrator is reserved for people who actually need it, not the marketing intern who edits blog posts.
Rotate credentials when team members leave. Audit the user list quarterly — old contractors and former employees with active accounts are common findings on first-time security audits. Application Passwords, the WordPress feature for API access via token rather than user password, should only be enabled for accounts that actually need API access. Don't enable it site-wide.
WAF and edge protection
A web application firewall in front of WordPress is the single highest-leverage upgrade most sites can make. Cloudflare's free tier is enough for most small business sites — managed rulesets, basic rate limiting, edge bot blocking. Sucuri and Akamai are reasonable upgrades for higher-stakes sites. The key property: an edge WAF stops attacks before they hit PHP, which means even a poorly-hardened WordPress core is shielded from most automated attacks.
Whichever WAF you use, configure rate limits aggressively on /wp-login.php, /xmlrpc.php, and /wp-json/. Block known bad bot user agents at the edge — there are public lists, and most WAF vendors include curated ones. Geo-blocking is pragmatic for many sites; for an Idaho-based business serving North American clients, blocking inbound traffic from regions where you have no business presence is a reasonable default.
Backups and recovery posture
The 3-2-1 rule: three copies of your data, on two different media, with at least one copy offsite. Daily database backups, weekly full-file-system backups, retained for at least 30 days. Where backups should not live: in the same WP-managed folder as the site (the attacker has those too), or under the same hosting account credentials. If your backup vendor uses the same login as your hosting, a single compromised credential loses both.
Test the restore quarterly. A backup you have not tested is not a backup — it's an unverified blob. The number of times we've found broken backup pipelines on first-time audits is embarrassingly high. Make "successfully restore staging from last night's backup" a recurring calendar item, not a theoretical capability.
Monitoring and incident response
File integrity monitoring should alert on unexpected changes to core files. A modified wp-load.php is almost never benign. Failed login alert thresholds catch credential-stuffing campaigns in progress. 404 spike alerts often signal automated scanning before a targeted attempt.
Write the incident-response playbook before you need it. Who calls hosting? Who notifies users? What gets disclosed when? For agency clients, clarify upfront who owns IR — most contracts are silent on this, which means the answer becomes "whoever's on the phone at 2 AM." A short written playbook — even just one page — turns a panic into a sequence.
For developers — secure coding patterns
Most security work in WordPress development happens inside hook callbacks. The patterns that matter:
- Always nonce-verify form submissions.
wp_create_nonce()on output,wp_verify_nonce()orcheck_admin_referer()on submission. - Always escape output.
esc_html,esc_attr,esc_url,wp_ksesfor filtered HTML. - Always sanitize input.
sanitize_text_field,sanitize_email, and friends — never trust raw$_POST. - Capability checks before privileged actions.
current_user_can()before any operation that mutates state or reads sensitive data. - Prepared statements for SQL.
$wpdb->prepare()with placeholders. Never concatenate.
A minimal hardened form-handler hook callback looks like this:
add_action( 'admin_post_save_settings', 'mxt_save_settings' );
function mxt_save_settings() {
// 1. Capability gate
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( 'Insufficient permissions.' );
}
// 2. Nonce check
check_admin_referer( 'mxt_save_settings_nonce' );
// 3. Sanitize input
$api_key = isset( $_POST['api_key'] )
? sanitize_text_field( wp_unslash( $_POST['api_key'] ) )
: '';
// 4. Persist with the option API (no raw SQL)
update_option( 'mxt_api_key', $api_key );
// 5. Redirect — never echo direct from a POST handler
wp_safe_redirect( admin_url( 'options-general.php?page=mxt-settings&saved=1' ) );
exit;
}For the deeper pattern guide on hook design, see Understanding WordPress Hooks: Actions and Filters.
The 2026 WordPress security checklist
Order is roughly by impact-to-effort:
- - [ ] All admin and editor accounts use 2FA via authenticator app
- - [ ] WordPress core auto-updates enabled; plugins auto-update where supported
- - [ ] An edge WAF (Cloudflare, Sucuri, or equivalent) sits in front of the site
- - [ ] Rate limits configured on /wp-login.php, /xmlrpc.php, /wp-json/
- - [ ]
DISALLOW_FILE_EDITset in wp-config.php - - [ ] HTTPS forced site-wide with HSTS preload
- - [ ] Unique salts in wp-config.php
- - [ ] Database user has least-privilege (no DROP/ALTER unless needed)
- - [ ] All plugins in active development; deactivated plugins removed
- - [ ] A paid security scanner is alerting on file integrity changes
- - [ ] 3-2-1 backups, with last successful restore test within the last 90 days
- - [ ] User list audited within the last 90 days; ex-staff accounts removed
- - [ ] Application Passwords disabled except for accounts that need API access
- - [ ] Written incident-response playbook on file
- - [ ] Vulnerability feed subscribed; patch SLA defined (24h critical, 7d high)
Security isn't a state — it's a practice. Quarterly review, every time. The sites that don't get breached are rarely the ones running exotic security setups; they're the ones doing this short list well. If you want this baked in by default — proper hardening, ongoing monitoring, patch SLAs — that's what our WordPress development and the MantleWP maintenance product are built for.
Need help putting this into practice?
MaxtDesign builds the AI-powered web stacks the articles describe — from agentic workflows to performance-first WordPress + WooCommerce. Talk to us about your project.