WordPress powers over 40% of the web, which makes it a prime target for automated attacks. The good news: most successful WordPress hacks exploit well-known, easily preventable vulnerabilities. This checklist walks you through every layer of WordPress security, from transport encryption to server-level hardening. Work through it systematically, and your site will be significantly harder to compromise than the vast majority of WordPress installations out there.
Securing Your WordPress Site with SSL and HTTPS
HTTPS encrypts all data traveling between your visitors' browsers and your server. Without it, login credentials, form submissions, and session cookies are transmitted in plain text, making them trivial to intercept on public networks.
- Install a valid SSL certificate: Most hosting providers offer free Let's Encrypt certificates that auto-renew every 90 days. If your host does not support Let's Encrypt, Cloudflare's free plan includes a shared SSL certificate. There is no reason to run without HTTPS in 2025.
- Redirect all HTTP traffic to HTTPS: Set up a 301 redirect so that every request to
http://is permanently forwarded tohttps://. On Apache, add this to your.htaccess:
On Nginx, add a server block that redirects:RewriteEngine On RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]server { listen 80; server_name example.com www.example.com; return 301 https://$host$request_uri; } - Fix all mixed content warnings: After switching to HTTPS, check for images, scripts, or stylesheets still loading over HTTP. The browser console will flag these as "Mixed Content" warnings. Update hardcoded
http://URLs in your database using a search-and-replace tool like Better Search Replace. - Enable the HSTS header: HTTP Strict Transport Security tells browsers to always use HTTPS for your domain, even if a user types
http://manually. Add this header with a max-age of at least six months (15768000 seconds). Only enableincludeSubDomainsif all your subdomains also support HTTPS.
Configuring HTTP Security Headers for WordPress
Security headers are instructions your server sends to the browser. They cost nothing in terms of performance but provide substantial protection against common attack vectors like clickjacking, MIME-type confusion, and cross-site scripting.
- X-Frame-Options: SAMEORIGIN: Prevents your pages from being embedded in iframes on other domains. This blocks clickjacking attacks where an attacker overlays your site with invisible elements to trick users into clicking something they did not intend to.
- X-Content-Type-Options: nosniff: Stops browsers from guessing the MIME type of a file. Without this header, a browser might execute a text file as JavaScript if the content looks like code, which opens the door to script injection.
- Referrer-Policy: strict-origin-when-cross-origin: Controls how much URL information is sent when navigating to external sites. This prevents leaking sensitive URL parameters (like password-reset tokens) to third-party servers.
- Permissions-Policy: Restricts access to browser features like camera, microphone, geolocation, and payment APIs for embedded content. Even if you do not use these features, setting the policy prevents injected scripts from abusing them.
- Content-Security-Policy (CSP): The most powerful security header, but also the most complex to configure. CSP defines which sources are allowed to load scripts, styles, images, and other resources. Start with
Content-Security-Policy-Report-Onlyto monitor violations without breaking your site, then gradually tighten the policy. A minimal starting point:Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;
You can set these headers in your .htaccess file (Apache), your Nginx config, or via a WordPress security plugin. If you use Cloudflare, you can also configure most of them under Security > Settings.
WordPress Core Hardening Techniques
WordPress itself is well-maintained and regularly patched, but its default configuration leaves several doors open that you should close deliberately.
- Keep WordPress core, plugins, and themes updated: The majority of WordPress hacks exploit known vulnerabilities in outdated software. Enable automatic minor updates (they are on by default) and check for major updates at least weekly. Consider enabling automatic plugin updates for trusted plugins.
- Remove unused plugins and themes completely: Deactivating a plugin does not remove its code from your server. An attacker can still exploit vulnerabilities in deactivated plugins. Delete anything you are not actively using, and keep only one default theme as a fallback.
- Disable XML-RPC: The XML-RPC interface (
/xmlrpc.php) was designed for remote publishing and pingbacks. Today, it is mainly abused for brute-force amplification attacks and DDoS. Unless you need it for Jetpack or the WordPress mobile app, disable it entirely. You can block it at the server level:# Apache .htaccess <Files xmlrpc.php> Order Deny,Allow Deny from all </Files> - Restrict the REST API user endpoint: By default,
/wp-json/wp/v2/usersexposes usernames to anyone. This makes it trivial for attackers to discover valid login names. Restrict this endpoint to authenticated requests only, either with a plugin or a custom code snippet. - Block user enumeration via author archives: Even without the REST API, attackers can discover usernames by requesting
/?author=1,/?author=2, etc. Block this by redirecting author archive requests or by disabling them entirely if your site does not need them. - Remove the WordPress version number: WordPress outputs its version in a meta tag and in the URLs of core CSS/JS files. While security through obscurity alone is insufficient, removing the version number forces attackers to probe rather than simply look up known vulnerabilities for your exact version.
- Secure or delete the debug.log file: When
WP_DEBUG_LOGis enabled, WordPress writes errors to/wp-content/debug.log. This file can contain database queries, file paths, plugin errors, and other information useful to attackers. Never leave debug logging enabled on production, and if the file exists, delete it or block access to it. - Use strong, unique passwords and enable two-factor authentication: Every WordPress account should have a password that is at least 16 characters long and unique to that site. Add two-factor authentication (2FA) with a plugin like WP 2FA or Wordfence Login Security. This single measure blocks virtually all brute-force attacks.
- Limit login attempts: WordPress allows unlimited login attempts by default. Use a plugin like Limit Login Attempts Reloaded to lock out IP addresses after a few failed tries, or use a Web Application Firewall (WAF) that includes brute-force protection.
- Change the default database table prefix: WordPress uses
wp_as the default table prefix. Changing it to something unique during installation makes automated SQL injection attacks slightly harder. If your site is already live, you can still change it, but back up your database first.
WordPress File Permissions and Server Security
File permissions determine who can read, write, and execute files on your server. Incorrect permissions are one of the most common security misconfigurations.
- Set correct file permissions: Use 644 for files and 755 for directories. The
wp-config.phpfile should be set to 600 or 640 on most hosting environments. Never use 777, which gives full read/write/execute access to everyone. - Protect wp-config.php from web access: This file contains your database credentials, authentication keys, and salts. On Apache, add this to
.htaccess:
Some security guides suggest moving<Files wp-config.php> Order Allow,Deny Deny from all </Files>wp-config.phpone directory above the web root. This works on most setups but can cause issues with some hosting providers. - Disable the built-in file editor: WordPress includes a file editor in the admin panel that lets administrators modify theme and plugin files directly. If an attacker gains admin access, this editor gives them the ability to inject malicious code into any PHP file. Disable it by adding this line to
wp-config.php:define('DISALLOW_FILE_EDIT', true); - Block access to sensitive files: Files like
readme.html,license.txt, andwp-config-sample.phpreveal information about your WordPress version and configuration. Block public access to them via your server configuration. - Disable directory browsing: If directory listing is enabled, anyone can browse your
/wp-content/uploads/folder and see every file you have uploaded. Disable it by addingOptions -Indexesto your.htaccess.
WordPress Backup Strategy and Recovery Planning
No security setup is complete without a reliable backup strategy. If the worst happens, a recent backup is the difference between a minor inconvenience and a total loss.
- Automate daily backups: Use a plugin like UpdraftPlus, BlogVault, or BackWPup to run automatic backups on a schedule. At minimum, back up daily. High-traffic sites or WooCommerce stores should consider real-time backups.
- Store backups off-site: Keep copies on a remote service like Amazon S3, Google Cloud Storage, or Dropbox. If your server is compromised, local backups may also be affected.
- Test your restore process: A backup you have never tested is a backup you cannot trust. Restore your backup to a staging environment at least once a quarter to confirm it works.
- Keep multiple backup generations: Maintain at least 30 days of daily backups. Some infections go undetected for weeks, so you need the ability to roll back to a known-clean state.
Ongoing Security Monitoring for WordPress
Security is not a one-time project. New vulnerabilities are discovered regularly, and your site's configuration can drift over time as plugins are added or settings change.
- Install a security plugin: Wordfence, Sucuri, or NinjaFirewall provide real-time protection including firewall rules, malware scanning, and login security. Choose one (not multiple, as they can conflict) and configure its alerts.
- Set up automated InspectWP scans: Schedule regular scans to monitor your security posture over time. InspectWP will alert you to new issues like missing headers, exposed debug logs, or version number leaks as soon as they appear.
- Enable update notifications: Make sure WordPress sends you email notifications when core, plugin, or theme updates are available. Security patches often need to be applied within hours of release to stay ahead of automated exploits.
- Review user accounts regularly: Remove inactive accounts, especially those with administrator or editor roles. Audit your user list at least monthly, and immediately revoke access for anyone who no longer needs it.
- Monitor your access logs: Check your server logs for unusual patterns, such as repeated requests to
/wp-login.php,/xmlrpc.php, or paths that do not exist. Many security plugins provide a simplified log view.
Verify Your WordPress Security with InspectWP
Run a comprehensive InspectWP scan to check all security-related items at once. The security section covers SSL configuration, HTTP security headers, WordPress version exposure, REST API user enumeration, debug log accessibility, and more. Set up automatic scans to receive notifications whenever your security posture changes, so you can address new issues before they are exploited.