WordPress Security Hardening Checklist: 50 Essential Steps
Complete WordPress security hardening checklist covering server configuration, WordPress settings, user management, and monitoring essentials.
This comprehensive checklist covers essential security hardening steps for WordPress sites. Use it as a reference for initial setup and ongoing security maintenance.
Server and Hosting Security
- [ ] Use a reputable hosting provider with security features
- [ ] Enable SSL/TLS certificate (HTTPS)
- [ ] Keep server software updated (PHP, MySQL, web server)
- [ ] Use latest stable PHP version (8.0+)
- [ ] Disable directory browsing
- [ ] Restrict file permissions (644 for files, 755 for directories)
- [ ] Set wp-config.php to 400 or 440
- [ ] Use SFTP instead of FTP
- [ ] Enable server-level firewall
- [ ] Configure ModSecurity or similar WAF
WordPress Core Configuration
- [ ] Keep WordPress core updated
- [ ] Use strong database table prefix (not wp_)
- [ ] Move wp-config.php above web root if possible
- [ ] Define security keys and salts
- [ ] Disable file editing in dashboard
- [ ] Disable debug mode in production
- [ ] Set proper authentication keys
wp-config.php Security Settings
// Disable file editing
define('DISALLOW_FILE_EDIT', true);
// Disable plugin/theme installation (optional)
define('DISALLOW_FILE_MODS', true);
// Force SSL for admin
define('FORCE_SSL_ADMIN', true);
// Limit post revisions
define('WP_POST_REVISIONS', 5);
// Disable debugging
define('WP_DEBUG', false);
define('WP_DEBUG_LOG', false);
define('WP_DEBUG_DISPLAY', false);
User Account Security
- [ ] Use unique, strong admin username (not "admin")
- [ ] Enforce strong password policy
- [ ] Enable two-factor authentication
- [ ] Limit login attempts
- [ ] Set proper user roles (principle of least privilege)
- [ ] Regularly audit user accounts
- [ ] Remove inactive user accounts
- [ ] Disable user registration if not needed
Password Policy Implementation
// Enforce minimum password strength
add_action('user_profile_update_errors', function($errors, $update, $user) {
if (isset($_POST['pass1']) && strlen($_POST['pass1']) > 0) {
$password = $_POST['pass1'];
if (strlen($password) < 12) {
$errors->add('weak_password', 'Password must be at least 12 characters');
}
if (!preg_match('/[A-Z]/', $password)) {
$errors->add('weak_password', 'Password must contain uppercase letter');
}
if (!preg_match('/[0-9]/', $password)) {
$errors->add('weak_password', 'Password must contain number');
}
if (!preg_match('/[^A-Za-z0-9]/', $password)) {
$errors->add('weak_password', 'Password must contain special character');
}
}
}, 10, 3);
Plugin and Theme Security
- [ ] Install plugins from trusted sources only
- [ ] Keep all plugins updated
- [ ] Remove unused plugins completely
- [ ] Use themes from reputable sources
- [ ] Keep themes updated
- [ ] Delete unused themes (keep one default)
- [ ] Verify plugin authenticity before installation
- [ ] Review plugin permissions and access
Login Security
- [ ] Change default login URL
- [ ] Implement CAPTCHA or reCAPTCHA
- [ ] Add login rate limiting
- [ ] Enable automatic lockout for failed attempts
- [ ] Hide login error messages
- [ ] Disable XML-RPC if not needed
- [ ] Whitelist login IPs if practical
Custom Login URL Example
// Redirect default login to custom URL
add_action('init', function() {
$custom_login = 'my-secret-login';
// Allow access to custom login
if (strpos($_SERVER['REQUEST_URI'], $custom_login) !== false) {
return;
}
// Block wp-login.php direct access
if (strpos($_SERVER['REQUEST_URI'], 'wp-login.php') !== false) {
if (!isset($_GET['action']) || $_GET['action'] !== 'logout') {
wp_redirect(home_url('404'));
exit;
}
}
});
Database Security
- [ ] Use unique database name
- [ ] Create dedicated database user
- [ ] Limit database user privileges
- [ ] Change default table prefix
- [ ] Regular database backups
- [ ] Encrypt database connection if remote
File System Security
- [ ] Protect wp-config.php via .htaccess
- [ ] Disable PHP execution in uploads folder
- [ ] Protect .htaccess file itself
- [ ] Block access to sensitive files
- [ ] Implement file integrity monitoring
.htaccess Security Rules
# Protect wp-config.php
<Files wp-config.php>
Order Allow,Deny
Deny from all
</Files>
# Protect .htaccess
<Files .htaccess>
Order Allow,Deny
Deny from all
</Files>
# Block sensitive files
<FilesMatch "(^\.|wp-config\.php|readme\.html|license\.txt)$">
Order Allow,Deny
Deny from all
</FilesMatch>
# Disable PHP in uploads
<Directory "/wp-content/uploads">
<Files "*.php">
Order Allow,Deny
Deny from all
</Files>
</Directory>
HTTP Security Headers
- [ ] Implement Content-Security-Policy
- [ ] Add X-Frame-Options header
- [ ] Set X-Content-Type-Options to nosniff
- [ ] Configure Strict-Transport-Security
- [ ] Set Referrer-Policy
- [ ] Add Permissions-Policy
Monitoring and Logging
- [ ] Enable security logging
- [ ] Monitor login attempts
- [ ] Track file changes
- [ ] Set up security alerts
- [ ] Regular security scans
- [ ] Monitor server logs
Backup Strategy
- [ ] Automated daily backups
- [ ] Store backups off-site
- [ ] Test backup restoration
- [ ] Encrypt backup files
- [ ] Retain multiple backup versions
Ongoing Maintenance
- [ ] Monthly security audits
- [ ] Quarterly penetration testing
- [ ] Regular vulnerability scanning
- [ ] Update security policies
- [ ] Train team on security practices
Conclusion
This checklist provides a foundation for WordPress security. Prioritize items based on your site risk level and implement them systematically. Regular review and updates ensure ongoing protection against evolving threats.
Written by Sarah Chen
WP Folder Shield Team