Advertisement
[Responsive Ad - 728x90]
#Security #HackingPrevention #Firewall #Malware WordPress 6.9

🛡️ WordPress 6.9 Security Guide: Protect Your Site from Hackers 2026

Complete security guide to prevent hacking, malware, and attacks. Learn hardening, firewall setup, PHP 8.3 security features, and monitoring. 50+ actionable steps to lock down your site.

Current Site Security Score (average) 42% - At Risk
42%

After implementing this guide: 95%+ Protected

50+
Security Tips

Blogs Team

Security Experts • 2026 Edition

🔰 Security Basics: First Line of Defense (Tips 1-5)

1

Keep Everything Updated

90% of hacked sites were running outdated software. Enable automatic updates.

// wp-config.php - Force automatic updates
define('WP_AUTO_UPDATE_CORE', true);
add_filter('auto_update_plugin', '__return_true');
add_filter('auto_update_theme', '__return_true');
Core Updates
Enable auto
Plugin Updates
Enable auto
Theme Updates
Enable auto
2

Use Strong Passwords & Password Manager

Weak passwords cause 30% of breaches. Use 16+ characters with special chars.

❌ Password123
❌ admin2026
✅ J#9kL$2mP@5qR&7x
✅ G%8nB^3vF*6tY~4w

Recommended: 1Password, Bitwarden, LastPass

3

Remove Default Admin User

Never use 'admin' as username. Create new admin and delete default.

-- SQL to check for admin user
SELECT * FROM wp_users WHERE user_login = 'admin';

-- Create new admin via WP-CLI
wp user create newadmin email@domain.com --role=administrator
wp user delete 1 --reassign=newadmin
4

Change Database Table Prefix

Default 'wp_' makes SQL injection easier. Change during install or with plugin.

// wp-config.php - Change prefix
$table_prefix = 'wp_6a9k2m_'; // Random 8 chars + underscore

⚠️ Only change during fresh install or with backup

5

Disable File Editing in Dashboard

Prevent hackers from editing theme/plugin files via admin.

// wp-config.php
define('DISALLOW_FILE_EDIT', true);
Impact: Blocks theme/plugin editor in admin
Advertisement
[Responsive Medium Rectangle - 300x250]

⚙️ PHP 8.3 Advanced Security Features (Tips 6-10)

6

Enable PHP 8.3's Random Extension

Use cryptographically secure random number generator for tokens and passwords.

// PHP 8.3 secure random generator
$token = bin2hex(random_bytes(32)); // 64 char secure token

// For passwords - use native functions
$hash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
if (password_verify($password, $hash)) {
    // Authenticated
}
7

Configure php.ini Security Settings

; Critical PHP security settings
disable_functions = exec,shell_exec,system,passthru,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source
allow_url_fopen = Off
allow_url_include = Off
expose_php = Off
display_errors = Off
log_errors = On
error_log = /path/to/php-errors.log
session.cookie_httponly = 1
session.cookie_secure = 1
session.use_strict_mode = 1
session.use_only_cookies = 1
8

Implement Content Security Policy Headers

# .htaccess - CSP Headers
Header set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https://cdnjs.cloudflare.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self'; connect-src 'self'; frame-ancestors 'self'; form-action 'self';"
9

Enable XSS Protection Headers

# Security Headers
Header set X-XSS-Protection "1; mode=block"
Header set X-Content-Type-Options "nosniff"
Header set X-Frame-Options "SAMEORIGIN"
Header set Referrer-Policy "strict-origin-when-cross-origin"
Header set Permissions-Policy "geolocation=(), microphone=(), camera=()"
10

Use Sodium for Encryption

// PHP 8.3 Sodium encryption
// Encrypt sensitive data
$key = sodium_crypto_secretbox_keygen();
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$encrypted = sodium_crypto_secretbox($data, $nonce, $key);

// Decrypt
$decrypted = sodium_crypto_secretbox_open($encrypted, $nonce, $key);

🔐 Authentication & Login Security (Tips 11-15)

11

Enable Two-Factor Authentication (2FA)

2FA blocks 99.9% of automated attacks.

Google Authenticator
Free
Authy
Free
WP 2FA
Plugin
12

Limit Login Attempts

// functions.php - Custom login limiting
function check_login_attempts($username) {
    $ip = $_SERVER['REMOTE_ADDR'];
    $attempts = get_transient('login_attempts_' . $ip);
    
    if ($attempts && $attempts >= 5) {
        return new WP_Error('too_many_attempts', 'Too many login attempts. Try again in 15 minutes.');
    }
    
    set_transient('login_attempts_' . $ip, $attempts + 1, 900);
    return $username;
}
add_filter('authenticate', 'check_login_attempts', 30, 2);
13

Change Login URL

Hide wp-admin from bots and automated attacks.

// functions.php - Change login URL
function custom_login_url() {
    return home_url('/secure-access');
}
add_filter('login_url', 'custom_login_url');

// Also in .htaccess
RewriteRule ^wp-admin$ - [F]
RewriteRule ^wp-login\.php$ - [F]
14

Use reCAPTCHA on Login

<!-- Add to login form -->
<script src="https://www.google.com/recaptcha/api.js"></script>
<div class="g-recaptcha" data-sitekey="YOUR_SITE_KEY"></div>

<?php
// Verify on login
$recaptcha = $_POST['g-recaptcha-response'];
$response = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=YOUR_SECRET&response={$recaptcha}");
if (!$response['success']) {
    wp_die('reCAPTCHA verification failed');
}
?>
15

Force Strong Passwords for All Users

// functions.php - Password strength enforcement
function enforce_strong_password($errors, $update, $user) {
    $password = $_POST['pass1'] ?? '';
    
    if (strlen($password) < 12) {
        $errors->add('weak_password', 'Password must be at least 12 characters');
    }
    
    if (!preg_match('/[!@#$%^&*]/', $password)) {
        $errors->add('weak_password', 'Password must contain special character');
    }
    
    return $errors;
}
add_filter('user_profile_update_errors', 'enforce_strong_password', 10, 3);
Advertisement
[Responsive Leaderboard]

📁 File Permissions & Ownership (Tips 16-20)

16

Set Correct File Permissions

# Standard WordPress permissions
find /path/to/wordpress -type d -exec chmod 755 {} \;
find /path/to/wordpress -type f -exec chmod 644 {} \;

# Special directories need 775 for uploads
chmod 775 wp-content/uploads
chmod 775 wp-content/cache

# Critical files should be 600
chmod 600 wp-config.php
chmod 600 .htaccess
17

Secure wp-config.php Location

Move wp-config.php one level above public_html.

# Directory structure
/home/user/
├── wp-config.php        # Moved up one level
└── public_html/         # WordPress core
    ├── wp-admin/
    ├── wp-content/
    └── wp-includes/
18

Protect Sensitive Files with .htaccess

# Block access to sensitive files
<FilesMatch "^(wp-config\.php|install\.php|php\.ini|\.htaccess)">
    Order Allow,Deny
    Deny from all
</FilesMatch>

# Disable directory browsing
Options -Indexes

# Protect includes directory
<IfModule mod_rewrite.c>
    RewriteRule ^wp-admin/includes/ - [F]
    RewriteRule ^wp-includes/[^/]+\.php$ - [F]
</IfModule>
19

Disable PHP Execution in Uploads

# In wp-content/uploads/.htaccess
<Files *.php>
    deny from all
</Files>

# Or more thorough
<IfModule mod_php7.c>
    php_flag engine off
</IfModule>
20

Regular File Integrity Scanning

#!/bin/bash
# Weekly file integrity check
cd /path/to/wordpress
find . -type f -name '*.php' -mtime -7 -exec ls -la {} \; > changed_files.txt

# Check against WordPress core checksums
wp core verify-checksums > core_verification.txt

# Monitor for suspicious files
find . -name '*.php' -exec grep -l "eval(" {} \; > suspicious.txt
find . -name '*.php' -exec grep -l "base64_decode" {} \; >> suspicious.txt

🛡️ Firewall & Web Application Firewall (Tips 21-25)

21

Use Cloudflare WAF

Cloudflare's free WAF blocks SQL injection, XSS, and DDoS attacks.

Enable:
  • Under Security → WAF
  • Turn on "Managed Ruleset"
  • Set to "High" sensitivity
Additional rules:
  • Block country access
  • Rate limiting
  • Bot fight mode
22

Install Wordfence Security Plugin

Most comprehensive WordPress firewall (free version available).

# Wordfence CLI scan
wordfence scan --malware --core --plugins --themes

# Real-time firewall rules
# Blocks malicious IPs, SQL injection, XSS
23

Create Custom .htaccess Firewall Rules

# Block malicious requests
RewriteCond %{QUERY_STRING} (eval\() [NC,OR]
RewriteCond %{QUERY_STRING} (base64_encode|base64_decode) [NC,OR]
RewriteCond %{QUERY_STRING} (union.*select.*\() [NC,OR]
RewriteCond %{QUERY_STRING} (concat.*\() [NC]
RewriteRule .* - [F]

# Block bad bots
RewriteCond %{HTTP_USER_AGENT} (ahrefs|semrush|majestic|archive) [NC]
RewriteRule .* - [F]

# Block certain HTTP methods
RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK|DELETE) [NC]
RewriteRule .* - [F]
24

Implement IP Blacklisting/Whitelisting

# Allow only specific IPs to wp-admin
<Files wp-login.php>
    Order Deny,Allow
    Deny from all
    Allow from 192.168.1.100  # Your IP
    Allow from 10.0.0.0/24     # Office network
</Files>

# Block known bad IPs
deny from 123.45.67.89
deny from 98.76.54.32
25

Enable Rate Limiting

# Nginx rate limiting
http {
    limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
    
    server {
        location /wp-login.php {
            limit_req zone=login burst=1 nodelay;
        }
    }
}

# Cloudflare rate limiting
# Security → WAF → Rate Limiting Rules
# Rule: 5 requests per minute to /wp-login.php
Advertisement
[Responsive Large Rectangle]

🗄️ Database Security Hardening (Tips 26-30)

26

Create Separate Database User

Never use root. Create limited user for WordPress only.

-- Create limited database user
CREATE USER 'wpuser'@'localhost' IDENTIFIED BY 'StrongPassword123!';
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, INDEX ON wordpress.* TO 'wpuser'@'localhost';
FLUSH PRIVILEGES;
27

Change Database Password Regularly

#!/bin/bash
# Monthly password rotation
NEW_PASS=$(openssl rand -base64 32)
mysql -e "ALTER USER 'wpuser'@'localhost' IDENTIFIED BY '$NEW_PASS';"
sed -i "s/define('DB_PASSWORD', '.*')/define('DB_PASSWORD', '$NEW_PASS')/" wp-config.php
28

Use Encrypted Database Connections

// wp-config.php - Force SSL for DB
define('MYSQL_CLIENT_FLAGS', MYSQLI_CLIENT_SSL);

# MySQL config - require SSL
[mysqld]
require_secure_transport = ON
ssl-ca = /path/to/ca.pem
ssl-cert = /path/to/server-cert.pem
ssl-key = /path/to/server-key.pem
29

Regular Database Backups

#!/bin/bash
# Daily encrypted backup
BACKUP_FILE="wp_backup_$(date +%Y%m%d).sql"
mysqldump -u wpuser -p wordpress > $BACKUP_FILE

# Encrypt backup
gpg --symmetric --cipher-algo AES256 $BACKUP_FILE

# Upload to secure storage
rclone copy ${BACKUP_FILE}.gpg remote:backups/

# Keep only last 30 days
find . -name "*.sql" -mtime +30 -delete
30

Remove Unused Database Tables

-- Find and drop unused plugin tables
SELECT table_name FROM information_schema.tables 
WHERE table_schema = 'wordpress' 
AND table_name LIKE '%_spam_%';

DROP TABLE wp_bad_plugin_table;

🔌 Plugin Security Best Practices (Tips 31-35)

31

Only Install from Trusted Sources

  • ✅ WordPress.org repository
  • ✅ Reputable developers (Yoast, WooCommerce, etc.)
  • ❌ Nulled/cracked plugins
  • ❌ Random GitHub repos
  • ❌ Torrent sites
32

Delete Unused Plugins

Inactive plugins can still be security risks.

# List all plugins
wp plugin list

# Delete inactive plugins
wp plugin delete $(wp plugin list --status=inactive --field=name)

# Or via SQL
DELETE FROM wp_options WHERE option_name LIKE '%plugin_name%';
33

Check Plugin Vulnerabilities

#!/bin/bash
# Check against WPScan vulnerability database
wpscan --url https://yoursite.com --api-token YOUR_TOKEN

# Or use CLI
wp plugin list --format=csv | while IFS=, read name status version
do
    curl "https://wpscan.com/api/v3/plugins/$name" -H "Authorization: Token token=YOUR_TOKEN"
done
34

Limit Plugin Capabilities

// functions.php - Restrict plugin access
function restrict_plugin_access() {
    if (!current_user_can('manage_options')) {
        deactivate_plugins(array('plugin-folder/plugin-file.php'));
    }
}
add_action('admin_init', 'restrict_plugin_access');

// Remove plugin menu for non-admins
if (!current_user_can('administrator')) {
    remove_menu_page('plugins.php');
}
35

Audit Plugin Code for Malware

#!/bin/bash
# Scan for suspicious patterns
grep -r "eval(" wp-content/plugins/
grep -r "base64_decode" wp-content/plugins/
grep -r "system(" wp-content/plugins/
grep -r "curl_" wp-content/plugins/
grep -r "preg_replace.*\/e" wp-content/plugins/

# Check for encrypted code
find wp-content/plugins/ -name "*.php" -exec grep -l "eval(gzinflate" {} \;
find wp-content/plugins/ -name "*.php" -exec grep -l "str_rot13" {} \;
Advertisement
[Responsive Leaderboard]

🔒 SSL & HTTPS Configuration (Tips 36-40)

36

Install SSL Certificate

Use Let's Encrypt for free, auto-renewing certificates.

# Install Certbot
sudo apt install certbot python3-certbot-apache

# Get certificate
sudo certbot --apache -d yourdomain.com -d www.yourdomain.com

# Auto-renewal
sudo certbot renew --dry-run
37

Force HTTPS Everywhere

// wp-config.php
define('FORCE_SSL_ADMIN', true);

# .htaccess - Force HTTPS
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]

# Nginx
server {
    listen 80;
    server_name yourdomain.com;
    return 301 https://$server_name$request_uri;
}
38

Use Strong SSL Configuration

# Nginx SSL configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_stapling on;
ssl_stapling_verify on;
39

Fix Mixed Content Warnings

// functions.php - Fix mixed content
function fix_mixed_content($content) {
    return str_replace('http://', 'https://', $content);
}
add_filter('the_content', 'fix_mixed_content');
add_filter('post_thumbnail_html', 'fix_mixed_content');
add_filter('wp_get_attachment_url', 'fix_mixed_content');

// Or use plugin: Really Simple SSL
40

Enable HSTS (HTTP Strict Transport Security)

# .htaccess
Header set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" env=HTTPS

# Nginx
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

# Submit to HSTS preload list
# https://hstspreload.org/

💾 Backup Security & Disaster Recovery (Tips 41-45)

41

Follow 3-2-1 Backup Rule

  • 3 copies of your data
  • 2 different storage types
  • 1 off-site backup
42

Encrypt Backups

#!/bin/bash
# Create encrypted backup
tar -czf wordpress.tar.gz /var/www/html
gpg --symmetric --cipher-algo AES256 wordpress.tar.gz
rm wordpress.tar.gz

# Store key separately
gpg --export-secret-keys > backup-key.asc

# Decrypt when needed
gpg --output wordpress.tar.gz --decrypt wordpress.tar.gz.gpg
tar -xzf wordpress.tar.gz
43

Test Backups Monthly

#!/bin/bash
# Automated restore testing
cd /tmp
gpg --decrypt latest-backup.tar.gz.gpg > backup.tar.gz
tar -xzf backup.tar.gz
docker run --rm -v $(pwd):/var/www/html wordpress:6.9 php /var/www/html/wp-admin/install.php
echo $?  # Check exit code
44

Secure Backup Storage

# AWS S3 with encryption
aws s3 cp backup.tar.gz.gzip s3://your-bucket/ --sse AES256

# With lifecycle policy
aws s3api put-bucket-lifecycle-configuration \
    --bucket your-bucket \
    --lifecycle-configuration file://lifecycle.json

# lifecycle.json
{
    "Rules": [{
        "Id": "Delete old backups",
        "Status": "Enabled",
        "Prefix": "",
        "Expiration": { "Days": 90 }
    }]
}
45

Create Disaster Recovery Plan

  1. Detect hack (monitoring alerts)
  2. Isolate site (maintenance mode)
  3. Restore from clean backup
  4. Change all passwords
  5. Scan for malware
  6. Update everything
  7. Investigate breach cause
  8. Reinforce security
  9. Bring site back online
  10. Document incident

📊 Security Monitoring & Audit Logs (Tips 46-50+)

46

Implement Audit Logging

// Custom audit log
function log_security_event($action, $details = []) {
    global $wpdb;
    
    $log = [
        'user_id' => get_current_user_id(),
        'action' => $action,
        'details' => json_encode($details),
        'ip' => $_SERVER['REMOTE_ADDR'],
        'user_agent' => $_SERVER['HTTP_USER_AGENT'],
        'timestamp' => current_time('mysql')
    ];
    
    $wpdb->insert($wpdb->prefix . 'security_audit', $log);
}

// Track logins
add_action('wp_login', function($user_login, $user) {
    log_security_event('login_success', ['user' => $user_login]);
}, 10, 2);

add_action('wp_login_failed', function($username) {
    log_security_event('login_failed', ['username' => $username]);
});
47

Set Up File Integrity Monitoring

#!/bin/bash
# AIDE - Advanced Intrusion Detection Environment
apt install aide
aideinit
mv /var/lib/aide/aide.db.new /var/lib/aide/aide.db

# Daily check
aide --check | mail -s "AIDE Report" admin@domain.com

# Tripwire alternative
tripwire --check
tripwire --update --twfile /etc/tripwire/tw.pol
48

Configure Real-Time Alerts

// Slack alerts for critical events
function send_slack_alert($message) {
    $webhook = 'https://hooks.slack.com/services/YOUR/WEBHOOK';
    
    $data = json_encode(['text' => $message]);
    
    wp_remote_post($webhook, [
        'headers' => ['Content-Type' => 'application/json'],
        'body' => $data
    ]);
}

// Alert on admin creation
add_action('user_register', function($user_id) {
    if (user_can($user_id, 'administrator')) {
        send_slack_alert("🚨 New admin created: User ID $user_id");
    }
});
49

Monitor Failed Login Attempts

#!/bin/bash
# Analyze auth logs
grep "Failed password" /var/log/auth.log | awk '{print $1,$2,$3,$11}' | sort | uniq -c | sort -nr

# Fail2ban configuration
apt install fail2ban
cat > /etc/fail2ban/jail.local << EOF
[wordpress]
enabled = true
port = http,https
filter = wordpress
logpath = /var/log/auth.log
maxretry = 5
bantime = 3600
EOF
50

Regular Security Audits

#!/bin/bash
# Monthly security audit script

echo "=== WordPress Security Audit ==="
date

echo -e "\n1. Checking WordPress version"
wp core version

echo -e "\n2. Verifying core files"
wp core verify-checksums

echo -e "\n3. Checking plugin vulnerabilities"
wpscan --url https://yoursite.com --api-token YOUR_TOKEN

echo -e "\n4. Scanning for malware"
clamscan -r /var/www/html/

echo -e "\n5. Checking file permissions"
find /var/www/html -type f -perm 777 -ls

echo -e "\n6. Reviewing user accounts"
wp user list

echo -e "\n7. Checking SSL expiration"
echo | openssl s_client -servername yoursite.com -connect yoursite.com:443 2>/dev/null | openssl x509 -noout -dates

echo -e "\n8. Testing backups"
ls -lh /backups/latest/

echo -e "\n=== Audit Complete ==="
+5

Bonus: 5 Advanced Security Tips

  • 51. Use Web Application Firewall (Cloudflare, Sucuri)
  • 52. Implement Security Headers scanner (securityheaders.com)
  • 53. Disable XML-RPC (add to .htaccess: RewriteRule ^xmlrpc.php - [F])
  • 54. Use Security Keys Salts generator (api.wordpress.org/secret-key/1.1/salt/)
  • 55. Regular penetration testing with tools like WPScan
Advertisement
[Responsive Large Rectangle]

✅ Security Checklist (Printable)

  • WordPress core updated
  • All plugins updated
  • All themes updated
  • Strong passwords enforced
  • 2FA enabled for all admins
  • Login attempt limiting
  • Default admin user removed
  • File permissions correct
  • wp-config.php secured
  • SSL/HTTPS enforced
  • Firewall enabled
  • Daily backups configured
  • Audit logging active
  • Security monitoring set up

⭐ Download PDF checklist: Security Checklist 2026

❓ Security FAQ

What's the most important security step?

Keeping everything updated. 90% of hacked sites were running outdated software.

Which security plugin is best?

Wordfence offers the most complete protection. Solid Security is great for hardening.

How often should I backup?

Daily for active sites, weekly for static sites. Store backups off-site encrypted.

What do I do if hacked?

1. Take site down 2. Restore from clean backup 3. Change all passwords 4. Find vulnerability

📬 Get Weekly Security Alerts & Tips

Stay ahead of hackers with latest vulnerabilities and fixes.

📢 Share this security guide to protect others