WordPress powers over 40% of all websites on the internet, which makes it the single most targeted platform by attackers. The default WordPress installation is reasonably secure, but default settings prioritize ease of use over security. Without hardening, a WordPress site on cPanel hosting exposes numerous attack surfaces that automated tools exploit around the clock.
This guide covers every hardening step you should implement, organized from the most critical to the most advanced. Each step includes specific instructions for cPanel hosting environments.
Before You Start: The Security Fundamentals
Before diving into technical hardening, ensure these basics are in place:
- Create a full backup — use cPanel's backup tool or a plugin like UpdraftPlus before making any changes
- Update everything — WordPress core, all plugins, and all themes should be at their latest versions
- Use a strong, unique password — at least 16 characters with a mix of letters, numbers, and symbols
- Enable two-factor authentication — on both cPanel and WordPress admin
- Verify your hosting provider's security — ensure they use CloudLinux CageFS and Imunify360
Step 1: Secure wp-config.php
The wp-config.php file contains your database credentials and security keys. It is the most sensitive file in your WordPress installation.
Move wp-config.php Above the Web Root
WordPress can automatically find wp-config.php one directory above the web root. If your WordPress is installed in /home/username/public_html/, move the file to /home/username/wp-config.php. This places it outside the publicly accessible directory, making it impossible to access via a web browser even if a misconfiguration occurs.
Set Correct File Permissions
In cPanel File Manager or via SSH, set wp-config.php permissions to 400 (read-only for the owner):
chmod 400 wp-config.php
If 400 causes issues with some hosting configurations, use 440 instead.
Add Security Keys
WordPress uses security keys (salts) to encrypt cookies and session tokens. If your wp-config.php still has the default placeholder keys, replace them with unique values from the WordPress salt generator:
# Visit this URL to generate new keys:
# https://api.wordpress.org/secret-key/1.1/salt/
Paste the generated keys into your wp-config.php, replacing the existing AUTH_KEY, SECURE_AUTH_KEY, LOGGED_IN_KEY, and related constants.
Disable File Editing
WordPress includes a built-in file editor that allows administrators to edit plugin and theme files from the dashboard. If an attacker gains admin access, this editor gives them the ability to inject malicious code. Disable it by adding to wp-config.php:
define('DISALLOW_FILE_EDIT', true);
Step 2: Secure File and Directory Permissions
Incorrect file permissions are one of the most common security vulnerabilities on shared hosting. Here are the correct permissions for WordPress on cPanel:
| File/Directory | Recommended Permission | Purpose |
|---|---|---|
| Directories | 755 | Owner: read/write/execute. Group/Others: read/execute |
| Files | 644 | Owner: read/write. Group/Others: read only |
| wp-config.php | 400 or 440 | Owner read-only (most restrictive) |
| .htaccess | 444 | Read-only for all (prevents modification) |
| wp-content/uploads | 755 | Needs write access for media uploads |
Set permissions via SSH:
# Set all directories to 755
find ~/public_html -type d -exec chmod 755 {} \;
# Set all files to 644
find ~/public_html -type f -exec chmod 644 {} \;
# Lock down wp-config.php
chmod 400 ~/public_html/wp-config.php
# Lock down .htaccess
chmod 444 ~/public_html/.htaccess
Important: Never set permissions to 777. This gives everyone read, write, and execute access and is a critical security vulnerability on shared hosting.
Step 3: Protect the Login Page
WordPress login pages (wp-login.php and wp-admin) are the most attacked endpoints on any WordPress site. Bots attempt thousands of password combinations daily.
Limit Login Attempts
Install a plugin like "Limit Login Attempts Reloaded" (free) or use Wordfence's brute-force protection. Configure it to lock out IPs after 3-5 failed attempts for at least 15 minutes. Imunify360, if your host uses it, provides server-level brute-force protection automatically.
Change the Login URL
Most brute-force bots target /wp-login.php and /wp-admin/ directly. Changing the login URL to something unique (like /my-secret-login) blocks the vast majority of automated attacks. Use the "WPS Hide Login" plugin (free) to change the URL without modifying core files.
Password-Protect wp-admin Directory
In cPanel, you can add an extra layer of password protection to the wp-admin directory using "Directory Privacy" (Directories > Directory Privacy). This creates an HTTP authentication prompt before visitors even see the WordPress login form, stopping bots that do not handle HTTP authentication.
Note: If you use AJAX on the front end of your site, you need to allow access to wp-admin/admin-ajax.php without the HTTP authentication prompt. Add this to wp-admin/.htaccess:
<Files admin-ajax.php>
Order allow,deny
Allow from all
Satisfy any
</Files>
Step 4: Secure the Database
Change the Table Prefix
WordPress uses wp_ as the default table prefix. This makes SQL injection attacks easier because attackers know the table names. While changing the prefix on an existing installation is complex (requires updating the database and wp-config.php), you should always use a custom prefix when setting up a new WordPress site. Choose something random like mg7x_ or k9qz_.
Restrict Database User Privileges
In cPanel > MySQL Databases, check the privileges assigned to your WordPress database user. For normal operation, WordPress needs: SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, INDEX, DROP. It does not need FILE, PROCESS, RELOAD, SHUTDOWN, or GRANT. Remove any unnecessary privileges.
Regular Database Optimization
Use phpMyAdmin (in cPanel) to regularly optimize your database tables. Go to phpMyAdmin, select your WordPress database, check all tables, and choose "Optimize table" from the dropdown. This removes overhead and improves query performance. Alternatively, install the WP-Optimize plugin for automated optimization.
Step 5: Harden .htaccess
Add these security rules to your root .htaccess file (above the WordPress rewrite rules):
# Protect wp-config.php
<Files wp-config.php>
Order Allow,Deny
Deny from all
</Files>
# Protect .htaccess itself
<Files .htaccess>
Order Allow,Deny
Deny from all
</Files>
# Prevent directory browsing
Options -Indexes
# Block PHP execution in uploads directory
<Directory "~/public_html/wp-content/uploads">
<Files "*.php">
Order Deny,Allow
Deny from all
</Files>
</Directory>
# Block access to sensitive files
<FilesMatch "(^\.htaccess|readme\.html|readme\.txt|license\.txt|wp-config\.php)$">
Order Allow,Deny
Deny from all
</FilesMatch>
# Disable XML-RPC (if not needed)
<Files xmlrpc.php>
Order Deny,Allow
Deny from all
</Files>
# Security headers
Header set X-Content-Type-Options "nosniff"
Header set X-Frame-Options "SAMEORIGIN"
Header set X-XSS-Protection "1; mode=block"
Header set Referrer-Policy "strict-origin-when-cross-origin"
Header set Permissions-Policy "geolocation=(), microphone=(), camera=()"
Block PHP Execution in Uploads
The wp-content/uploads directory should contain only media files, never PHP scripts. Malware frequently hides in this directory. Create a separate .htaccess file in wp-content/uploads/ with:
# Deny PHP execution in uploads
<Files *.php>
deny from all
</Files>
This prevents any PHP file in the uploads directory from executing, even if malware is successfully uploaded.
Step 6: Remove Information Disclosure
WordPress reveals information that attackers use for reconnaissance:
Remove the WordPress Version
Add to your theme's functions.php:
// Remove WordPress version from head and RSS
remove_action('wp_head', 'wp_generator');
// Remove version from scripts and styles
function remove_version_strings($src) {
if (strpos($src, 'ver=')) {
$src = remove_query_arg('ver', $src);
}
return $src;
}
add_filter('style_loader_src', 'remove_version_strings');
add_filter('script_loader_src', 'remove_version_strings');
Disable User Enumeration
Attackers can discover WordPress usernames by visiting yourdomain.com/?author=1. Block this by adding to .htaccess:
# Block user enumeration
RewriteCond %{QUERY_STRING} author=\d
RewriteRule ^ /? [L,R=301]
Remove readme.html and license.txt
These files reveal your WordPress version. Delete them from your WordPress root directory. Note that WordPress updates may recreate them, so check after each update.
Step 7: Install Security Plugins
Choose one comprehensive security plugin (not multiple, as they can conflict):
- Wordfence Security — firewall, malware scanner, login security, 2FA. Best free option.
- Sucuri Security — file integrity monitoring, blacklist monitoring, security hardening. Good complement to server-level security.
- iThemes Security — strong hardening options, file change detection, scheduled malware scanning.
These application-level security plugins complement server-level protection from Imunify360 and ModSecurity WAF. Use both layers for defense in depth.
Step 8: Manage Updates and Maintenance
Enable Auto-Updates for Core
Add to wp-config.php:
// Enable automatic updates for minor releases (security patches)
define('WP_AUTO_UPDATE_CORE', 'minor');
Manage Plugin and Theme Updates
In the WordPress dashboard, you can enable auto-updates for individual plugins and themes. Enable auto-updates for all plugins from reputable developers. For custom or less-tested plugins, update manually after verifying compatibility.
Remove Unused Plugins and Themes
Every installed plugin and theme (even inactive ones) represents potential attack surface. Delete — do not just deactivate — any plugins and themes you are not actively using. Keep only your active theme and one default theme (like Twenty Twenty-Five) as a fallback.
Step 9: Implement Backups
Backups are your last line of defense when all security measures fail. Implement a 3-2-1 backup strategy:
- 3 copies of your data
- 2 different storage media (hosting server + external)
- 1 offsite copy (cloud storage like Google Drive, Dropbox, or S3)
On cPanel hosting, combine:
- cPanel's built-in backup — full account backups (usually weekly)
- UpdraftPlus plugin — scheduled WordPress backups to cloud storage (daily database, weekly files)
- Hosting provider backups — MassiveGRID's cPanel hosting includes automatic server-level backups
Test your backups periodically by restoring to a staging environment. A backup you have never tested is not a backup you can trust.
WordPress Security Hardening Checklist
| Category | Action | Priority |
|---|---|---|
| Authentication | Enable 2FA on WordPress admin | Critical |
| Authentication | Use strong unique passwords | Critical |
| Authentication | Limit login attempts | Critical |
| Updates | Update WordPress core, plugins, themes | Critical |
| Configuration | Set correct file permissions (644/755) | Critical |
| Configuration | Disable file editor in wp-config.php | High |
| Configuration | Block PHP execution in uploads | High |
| Configuration | Disable XML-RPC (if unused) | High |
| Monitoring | Install security plugin (Wordfence) | High |
| Backups | Implement automated offsite backups | High |
| Privacy | Remove version information | Medium |
| Privacy | Block user enumeration | Medium |
| Access | Change login URL | Medium |
| Headers | Add security headers | Medium |
For a comprehensive pre-launch checklist covering hosting-level security in addition to WordPress hardening, see our hosting security checklist: 12 things to verify before going live.
Frequently Asked Questions
Is WordPress inherently insecure?
No. WordPress core is developed by a large security team and receives regular security patches. The vast majority of WordPress compromises result from outdated plugins, weak passwords, or misconfigured hosting — not from vulnerabilities in WordPress core. A properly hardened and maintained WordPress installation on quality hosting like MassiveGRID's cPanel hosting is a secure platform.
Do I need a security plugin if my host has Imunify360?
Imunify360 and WordPress security plugins protect at different levels. Imunify360 operates at the server level (scanning files, blocking network attacks, monitoring PHP execution). WordPress security plugins operate at the application level (hardening WordPress settings, monitoring WordPress-specific changes, securing the login page). Using both provides comprehensive defense in depth.
How often should I update WordPress and plugins?
Apply security updates within 24-48 hours of release. Feature updates can wait a few days to see if the community reports any issues. Enable auto-updates for WordPress minor releases (security patches) and set a weekly schedule to check for and apply plugin updates. Subscribe to the WordPress security mailing list or follow your security plugin's threat notifications for critical alerts.
Will security hardening break my website?
Most hardening steps are safe and non-disruptive. However, some changes (like blocking PHP execution in uploads or disabling XML-RPC) can affect plugins that depend on those features. Always create a backup before making changes, implement one change at a time, and test your site after each change. If something breaks, you can easily revert.
What is the most important WordPress security step?
If you can only do one thing, keep everything updated. The majority of WordPress compromises exploit known vulnerabilities in outdated plugins and themes for which patches already exist. Automatic updates for WordPress core and regular plugin updates close these vulnerabilities before attackers can exploit them. After updates, the next most impactful step is enabling two-factor authentication on all admin accounts.