WordPress security requires constant vigilance—manually checking for plugin vulnerabilities, monitoring file changes, detecting malware, verifying core integrity, and reviewing user permissions. Manual security audits happen infrequently and miss threats between checks.
Automated WordPress security scanning with WP-CLI detects vulnerabilities continuously, monitors file integrity, checks for malware patterns, validates checksums, and alerts on suspicious changes. Run comprehensive security scans daily without manual intervention.
In this guide, you’ll build automated WordPress security monitoring systems using WP-CLI, from basic vulnerability checks to production-grade security automation that protects your sites 24/7.
Why Automate WordPress Security?
Manual WordPress security checks don’t provide continuous protection against evolving threats.
Manual Security Limitations
Infrequent checks: Manual audits happen weekly or monthly, leaving gaps.
Human error: Manual reviews miss subtle security indicators.
Time-consuming: Comprehensive security audits take hours per site.
No real-time alerts: Breaches go undetected until the next manual check.
Limited scope: Can’t check every file, user, and configuration regularly.
Automated Security Benefits
Continuous monitoring: Security checks run automatically every day.
Instant alerts: Get notified immediately when threats are detected.
Comprehensive coverage: Scan every file, plugin, theme, and configuration.
Historical tracking: Log all security events for forensic analysis.
Multi-site management: Monitor dozens of WordPress sites from one system.
According to Sucuri research, automated security monitoring detects breaches 85% faster than manual audits.
Core File Integrity Verification
Detect unauthorized modifications to WordPress core files.
Checksum Verification
#!/bin/bash
# verify-core-integrity.sh
echo "WordPress Core Integrity Check"
echo "==============================="
# Verify core file checksums
if wp core verify-checksums; then
echo "✓ Core files verified - no modifications detected"
else
echo "✗ ALERT: Core files modified or corrupted"
echo "Details:"
wp core verify-checksums --format=json | jq -r '.[] | " - \(.)"'
# Send alert
echo "Core file integrity check failed on $(hostname)" | \
mail -s "WordPress Security Alert" admin@example.com
fiAutomated Daily Verification
#!/bin/bash
# daily-integrity-check.sh
LOG_FILE="/var/log/wp-security.log"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $@" | tee -a "$LOG_FILE"
}
log "Starting core integrity check"
# Check WordPress core
if ! wp core verify-checksums 2>&1 | tee -a "$LOG_FILE"; then
log "✗ Core integrity check FAILED"
# Create detailed report
{
echo "WordPress Core Integrity Failure"
echo "================================="
echo "Timestamp: $(date)"
echo "Server: $(hostname)"
echo "WordPress version: $(wp core version)"
echo ""
echo "Modified files:"
wp core verify-checksums 2>&1 | grep "^Error:"
} | mail -s "URGENT: WordPress Core Modified" security@example.com
exit 1
fi
log "✓ Core integrity check passed"Learn about WordPress file integrity.
Plugin and Theme Vulnerability Detection
Check for known security vulnerabilities in plugins and themes.
WP-CLI Vulnerability Scanner
#!/bin/bash
# scan-vulnerabilities.sh
echo "WordPress Vulnerability Scan"
echo "============================"
# Check if WPScan CLI is available
if ! command -v wpscan &> /dev/null; then
echo "Installing WPScan..."
gem install wpscan
fi
# Update WPScan database
wpscan --update
# Scan WordPress installation
SCAN_RESULTS=$(wpscan --url "$(wp option get siteurl)" \
--format json \
--random-user-agent \
--disable-tls-checks)
# Parse vulnerabilities
VULN_COUNT=$(echo "$SCAN_RESULTS" | jq '.plugins | to_entries[] | select(.value.vulnerabilities | length > 0) | .value.vulnerabilities | length' | awk '{s+=$1} END {print s}')
if [ "$VULN_COUNT" -gt 0 ]; then
echo "✗ ALERT: $VULN_COUNT vulnerabilities detected"
# Generate detailed report
echo "$SCAN_RESULTS" | jq -r '.plugins | to_entries[] | select(.value.vulnerabilities | length > 0) | "Plugin: \(.key)\nVulnerabilities:\n\(.value.vulnerabilities[] | " - \(.title) (Severity: \(.vuln_type))\n Fixed in: \(.fixed_in // "No fix available")\n")"'
else
echo "✓ No known vulnerabilities detected"
fiCheck Plugin Updates for Security Fixes
#!/bin/bash
# check-security-updates.sh
echo "Checking for security updates..."
# Get plugins with available updates
UPDATES=$(wp plugin list --update=available --format=json)
if [ "$UPDATES" != "[]" ]; then
echo "Plugins with available updates:"
echo "$UPDATES" | jq -r '.[] | "- \(.name) (Current: \(.version), Available: \(.update_version))"'
# Check update changelogs for security keywords
echo ""
echo "Checking changelogs for security mentions..."
echo "$UPDATES" | jq -r '.[].name' | while read PLUGIN; do
CHANGELOG=$(wp plugin get "$PLUGIN" --field=update_changelog 2>/dev/null)
if echo "$CHANGELOG" | grep -qi 'security\|vulnerability\|xss\|sql injection\|exploit'; then
echo "⚠ SECURITY UPDATE AVAILABLE: $PLUGIN"
echo " Update immediately using: wp plugin update $PLUGIN"
fi
done
else
echo "✓ All plugins up to date"
fiLearn about WordPress security best practices.
File Change Monitoring
Detect unauthorized file modifications.
File Integrity Database
#!/bin/bash
# create-file-baseline.sh - Create baseline of file checksums
BASELINE_FILE="/var/backups/wp-file-baseline.txt"
WP_PATH="/var/www/html"
echo "Creating file integrity baseline..."
cd "$WP_PATH"
# Generate checksums for all WordPress files
find . -type f \
-not -path "./wp-content/uploads/*" \
-not -path "./wp-content/cache/*" \
-not -path "./wp-content/backup/*" \
-exec md5sum {} \; | sort > "$BASELINE_FILE"
echo "✓ Baseline created: $BASELINE_FILE"
echo "Total files: $(wc -l < $BASELINE_FILE)"Detect File Changes
#!/bin/bash
# detect-file-changes.sh
BASELINE_FILE="/var/backups/wp-file-baseline.txt"
WP_PATH="/var/www/html"
REPORT_FILE="/tmp/file-changes-$(date +%Y%m%d).txt"
if [ ! -f "$BASELINE_FILE" ]; then
echo "ERROR: Baseline file not found. Run create-file-baseline.sh first."
exit 1
fi
echo "Scanning for file changes..."
cd "$WP_PATH"
# Generate current checksums
find . -type f \
-not -path "./wp-content/uploads/*" \
-not -path "./wp-content/cache/*" \
-not -path "./wp-content/backup/*" \
-exec md5sum {} \; | sort > /tmp/current-checksums.txt
# Compare with baseline
{
echo "WordPress File Change Report"
echo "============================="
echo "Date: $(date)"
echo ""
# Modified files
echo "Modified Files:"
comm -13 "$BASELINE_FILE" /tmp/current-checksums.txt | awk '{print $2}' | while read file; do
if grep -q "$file" "$BASELINE_FILE"; then
echo " MODIFIED: $file"
fi
done
echo ""
# New files
echo "New Files:"
comm -13 "$BASELINE_FILE" /tmp/current-checksums.txt | awk '{print $2}' | while read file; do
if ! grep -q "$file" "$BASELINE_FILE"; then
echo " ADDED: $file"
fi
done
echo ""
# Deleted files
echo "Deleted Files:"
comm -23 "$BASELINE_FILE" /tmp/current-checksums.txt | awk '{print $2}' | while read file; do
echo " DELETED: $file"
done
} > "$REPORT_FILE"
# Check if changes detected
CHANGE_COUNT=$(cat "$REPORT_FILE" | grep -c "MODIFIED:\|ADDED:\|DELETED:")
if [ "$CHANGE_COUNT" -gt 0 ]; then
echo "✗ ALERT: $CHANGE_COUNT file changes detected"
echo "Report: $REPORT_FILE"
# Email report
mail -s "WordPress File Changes Detected" admin@example.com < "$REPORT_FILE"
else
echo "✓ No file changes detected"
fi
# Cleanup
rm /tmp/current-checksums.txtMalware Pattern Scanning
Detect common malware patterns in WordPress files.
Basic Malware Scanner
#!/bin/bash
# scan-malware.sh - Detect common malware patterns
WP_PATH="/var/www/html"
REPORT_FILE="/tmp/malware-scan-$(date +%Y%m%d).txt"
echo "WordPress Malware Scan"
echo "======================"
# Suspicious patterns to check
declare -a PATTERNS=(
"eval(base64_decode"
"eval(gzinflate"
"eval(str_rot13"
"system(\$_"
"shell_exec"
"passthru"
"base64_decode.*eval"
"FilesMan"
"r57shell"
"c99shell"
"WSO shell"
)
{
echo "Malware Scan Report"
echo "==================="
echo "Date: $(date)"
echo "Path: $WP_PATH"
echo ""
for PATTERN in "${PATTERNS[@]}"; do
echo "Checking for: $PATTERN"
MATCHES=$(grep -r -l -i "$PATTERN" "$WP_PATH" \
--exclude-dir=wp-content/uploads \
--exclude-dir=wp-content/cache \
--exclude-dir=node_modules \
--include="*.php" 2>/dev/null)
if [ ! -z "$MATCHES" ]; then
echo "✗ SUSPICIOUS: Files matching '$PATTERN':"
echo "$MATCHES" | while read file; do
echo " - $file"
done
echo ""
fi
done
} > "$REPORT_FILE"
# Check if suspicious files found
SUSPICIOUS_COUNT=$(grep -c "✗ SUSPICIOUS:" "$REPORT_FILE" || echo 0)
if [ "$SUSPICIOUS_COUNT" -gt 0 ]; then
echo "✗ ALERT: Potential malware detected"
echo "Report: $REPORT_FILE"
# Send alert
mail -s "URGENT: Potential Malware Detected" security@example.com < "$REPORT_FILE"
else
echo "✓ No malware patterns detected"
fiCheck for Suspicious Files
#!/bin/bash
# check-suspicious-files.sh
WP_PATH="/var/www/html"
echo "Checking for suspicious files..."
# Check for unusual file types in wp-content
echo "Checking for executable files in wp-content..."
find "$WP_PATH/wp-content" \
-type f \
\( -name "*.exe" -o -name "*.sh" -o -name "*.bat" \) \
-print
# Check for PHP files in uploads directory
echo "Checking for PHP files in uploads..."
find "$WP_PATH/wp-content/uploads" -name "*.php" -print
# Check for recently modified files (last 24 hours)
echo "Recently modified PHP files (last 24 hours)..."
find "$WP_PATH" -name "*.php" -mtime -1 -type f -print
# Check for files with suspicious permissions
echo "Files with 777 permissions..."
find "$WP_PATH" -type f -perm 0777 -printLearn about WordPress malware detection.
User Account Security Auditing
Monitor user accounts for security issues.
User Security Audit
#!/bin/bash
# audit-users.sh
echo "WordPress User Security Audit"
echo "=============================="
# Check for users with admin privileges
echo "Administrator Accounts:"
wp user list --role=administrator --format=table --fields=ID,user_login,user_email,user_registered
ADMIN_COUNT=$(wp user list --role=administrator --format=count)
if [ "$ADMIN_COUNT" -gt 3 ]; then
echo "⚠ WARNING: $ADMIN_COUNT administrator accounts (recommended: 1-2)"
fi
echo ""
# Check for weak usernames
echo "Checking for common/weak usernames..."
WEAK_USERS=("admin" "administrator" "root" "test" "demo")
for USERNAME in "${WEAK_USERS[@]}"; do
if wp user get "$USERNAME" &>/dev/null; then
echo "✗ WARNING: Common username detected: $USERNAME"
echo " Recommended: Delete or rename this account"
fi
done
echo ""
# Check for inactive admin accounts
echo "Inactive Administrator Accounts (no posts/pages):"
wp user list --role=administrator --format=json | \
jq -r '.[] | select(.posts == "0") | "- \(.user_login) (registered: \(.user_registered))"'
echo ""
# Check user capabilities
echo "Users with 'delete_users' capability:"
wp user list --format=json | \
jq -r '.[] | select(.roles[] | contains("administrator")) | .user_login'Password Policy Check
#!/bin/bash
# check-password-policy.sh
echo "Password Policy Check"
echo "===================="
# This requires custom code to check password strength
# WordPress doesn't expose password hashes via WP-CLI for security
# Check for recent password changes
echo "Users who haven't changed password recently:"
# This would require custom user meta tracking
# Check for 2FA status (if plugin installed)
if wp plugin is-installed two-factor; then
echo "2FA Status:"
wp user list --format=json | \
jq -r '.[] | "\(.user_login): \(if .two_factor_enabled then "Enabled" else "DISABLED" end)"'
fi
# List users who can install plugins/themes
echo ""
echo "Users with plugin/theme installation privileges:"
wp user list --role=administrator,editor --format=csv --fields=user_login,rolesComprehensive Security Report
Generate complete security assessment reports.
Master Security Script
#!/bin/bash
# comprehensive-security-check.sh
REPORT_FILE="/tmp/wordpress-security-report-$(date +%Y%m%d).txt"
LOG_FILE="/var/log/wp-security.log"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $@" | tee -a "$LOG_FILE"
}
{
echo "WordPress Comprehensive Security Report"
echo "========================================"
echo "Generated: $(date)"
echo "Server: $(hostname)"
echo ""
# Core integrity
echo "1. Core File Integrity"
echo "----------------------"
if wp core verify-checksums; then
echo "✓ PASS: Core files verified"
else
echo "✗ FAIL: Core file modifications detected"
fi
echo ""
# Plugin security
echo "2. Plugin Security"
echo "------------------"
PLUGIN_UPDATES=$(wp plugin list --update=available --format=count)
echo "Plugins needing updates: $PLUGIN_UPDATES"
if [ "$PLUGIN_UPDATES" -eq 0 ]; then
echo "✓ PASS: All plugins up to date"
else
echo "⚠ WARNING: Plugin updates available"
wp plugin list --update=available --format=table --fields=name,version,update_version
fi
echo ""
# Theme security
echo "3. Theme Security"
echo "-----------------"
THEME_UPDATES=$(wp theme list --update=available --format=count)
echo "Themes needing updates: $THEME_UPDATES"
echo ""
# User accounts
echo "4. User Account Security"
echo "------------------------"
ADMIN_COUNT=$(wp user list --role=administrator --format=count)
echo "Administrator accounts: $ADMIN_COUNT"
if [ "$ADMIN_COUNT" -gt 3 ]; then
echo "⚠ WARNING: Too many administrator accounts"
else
echo "✓ PASS: Administrator count acceptable"
fi
echo ""
# SSL/HTTPS check
echo "5. SSL/HTTPS Configuration"
echo "--------------------------"
SITE_URL=$(wp option get siteurl)
if [[ "$SITE_URL" == https://* ]]; then
echo "✓ PASS: HTTPS enabled"
else
echo "✗ FAIL: Site not using HTTPS"
fi
echo ""
# File permissions
echo "6. File Permissions"
echo "-------------------"
INSECURE_FILES=$(find . -type f -perm 0777 | wc -l)
echo "Files with 777 permissions: $INSECURE_FILES"
if [ "$INSECURE_FILES" -eq 0 ]; then
echo "✓ PASS: No files with overly permissive permissions"
else
echo "⚠ WARNING: Insecure file permissions detected"
fi
echo ""
# WordPress version
echo "7. WordPress Version"
echo "--------------------"
CURRENT_VERSION=$(wp core version)
LATEST_VERSION=$(wp core check-update --format=json | jq -r '.[0].version // empty')
echo "Current version: $CURRENT_VERSION"
echo "Latest version: ${LATEST_VERSION:-$CURRENT_VERSION}"
if [ -z "$LATEST_VERSION" ]; then
echo "✓ PASS: WordPress is up to date"
else
echo "⚠ WARNING: WordPress update available"
fi
} > "$REPORT_FILE"
log "Security report generated: $REPORT_FILE"
# Email report
mail -s "WordPress Security Report - $(hostname)" admin@example.com < "$REPORT_FILE"
echo "✓ Security report complete: $REPORT_FILE"Automated Scheduling
Run security scans automatically with cron.
Cron Configuration
# Add to crontab: crontab -e
# Daily core integrity check at 2 AM
0 2 * * * /usr/local/bin/verify-core-integrity.sh >> /var/log/wp-security.log 2>&1
# Daily vulnerability scan at 3 AM
0 3 * * * /usr/local/bin/scan-vulnerabilities.sh >> /var/log/wp-security.log 2>&1
# Daily file change detection at 4 AM
0 4 * * * /usr/local/bin/detect-file-changes.sh >> /var/log/wp-security.log 2>&1
# Weekly comprehensive security report (Mondays at 8 AM)
0 8 * * 1 /usr/local/bin/comprehensive-security-check.sh
# Monthly user audit (first day of month)
0 9 1 * * /usr/local/bin/audit-users.sh | mail -s "Monthly User Audit" admin@example.comLearn about WordPress security monitoring.
Next Steps
You now have automated WordPress security scanning and monitoring capabilities with WP-CLI.
Recommended Learning Path
Week 1: Core security
- Implement core integrity checks
- Set up vulnerability scanning
- Test alerting systems
Week 2: File monitoring
- Create file baselines
- Configure change detection
- Add malware scanning
Week 3: User security
- Audit user accounts
- Check permissions
- Implement password policies
Week 4: Automation
- Schedule all security checks
- Configure comprehensive reports
- Integrate with monitoring tools
Advanced Topics
- Intrusion Detection Systems – Advanced threat detection
- Security Information and Event Management (SIEM) – Centralized security monitoring
- Automated Incident Response – Automatic threat mitigation
Get More Resources
Download security scripts including:
- Complete scanning system
- Monitoring tools
- Report templates
- Weekly WP-CLI tutorials
- Security best practices
- Threat response strategies
Conclusion
Automated WordPress security scanning with WP-CLI provides continuous protection against vulnerabilities, malware, and unauthorized changes—detecting threats before they compromise your sites.
What we covered:
✅ Core file integrity verification
✅ Plugin and theme vulnerability detection
✅ File change monitoring and alerting
✅ Malware pattern scanning
✅ User account security auditing
✅ Comprehensive automated security reports
Implement these security automation systems, and you’ll detect threats immediately—protecting WordPress sites 24/7 without constant manual monitoring.
Ready for more? Learn incident response or WordPress hardening.
Questions about WordPress security automation? Drop a comment below!
Found this helpful? Share with other WordPress administrators.
