Hardening

WordPress Database Security: Complete Protection Guide

Secure your WordPress database with table prefix changes, access controls, prepared statements, and encryption.

S
Sarah Chen
8 min read
1,598 views
WordPress database security and SQL injection prevention guide

Your WordPress database contains everything: posts, users, passwords, settings, and customer data. Protecting it from SQL injection, unauthorized access, and data theft is critical.

Database Security Fundamentals

What the Database Contains

  • User credentials (hashed passwords)
  • Email addresses and personal data
  • Plugin and theme settings
  • Posts, pages, and media references
  • E-commerce transactions

Table Prefix Security

Change Default Prefix

The default wp_ prefix makes SQL injection easier. Use a unique prefix.

// wp-config.php
$table_prefix = 'wpfs_8x7k_';

// Random prefix generator
$table_prefix = 'wp' . substr(md5(time()), 0, 6) . '_';

Changing Existing Prefix

-- Rename tables (backup first!)
RENAME TABLE wp_posts TO wpfs_8x7k_posts;
RENAME TABLE wp_users TO wpfs_8x7k_users;
-- Continue for all tables

-- Update options table
UPDATE wpfs_8x7k_options
SET option_name = REPLACE(option_name, 'wp_', 'wpfs_8x7k_')
WHERE option_name LIKE 'wp_%';

-- Update usermeta
UPDATE wpfs_8x7k_usermeta
SET meta_key = REPLACE(meta_key, 'wp_', 'wpfs_8x7k_')
WHERE meta_key LIKE 'wp_%';

SQL Injection Prevention

Always Use Prepared Statements

// WRONG - vulnerable to SQL injection
$wpdb->query("SELECT * FROM wp_posts WHERE ID = $_GET[id]");

// CORRECT - use prepare()
$wpdb->get_results(
    $wpdb->prepare(
        "SELECT * FROM {$wpdb->posts} WHERE ID = %d",
        intval($_GET['id'])
    )
);

// For strings
$wpdb->prepare(
    "SELECT * FROM {$wpdb->users} WHERE user_email = %s",
    sanitize_email($_POST['email'])
);

Parameterized Queries

// Insert with prepare
$wpdb->insert(
    $wpdb->posts,
    array(
        'post_title' => sanitize_text_field($title),
        'post_content' => wp_kses_post($content),
        'post_status' => 'publish'
    ),
    array('%s', '%s', '%s')
);

// Update with prepare
$wpdb->update(
    $wpdb->posts,
    array('post_title' => $new_title),
    array('ID' => $post_id),
    array('%s'),
    array('%d')
);

Database User Permissions

Principle of Least Privilege

-- Create dedicated WordPress user
CREATE USER 'wp_user'@'localhost' IDENTIFIED BY 'strong_password';

-- Grant only necessary permissions
GRANT SELECT, INSERT, UPDATE, DELETE
ON wordpress_db.* TO 'wp_user'@'localhost';

-- Avoid granting these unless needed
-- DROP, ALTER, CREATE, INDEX, GRANT

Separate Users for Tasks

  • Read-only user for reporting
  • Backup user with SELECT only
  • Admin user for migrations only

Database Connection Security

SSL/TLS Connection

// wp-config.php
define('MYSQL_CLIENT_FLAGS', MYSQLI_CLIENT_SSL);

// Or specify certificate
define('MYSQL_SSL_CA', '/path/to/ca-cert.pem');

Local Socket Connection

// Use socket instead of TCP when possible
define('DB_HOST', 'localhost:/var/run/mysql/mysql.sock');

Data Encryption

Encrypting Sensitive Data

// Encrypt before storing
function wpfs_encrypt($data) {
    $key = defined('WPFS_ENCRYPTION_KEY')
           ? WPFS_ENCRYPTION_KEY
           : AUTH_KEY;
    $iv = random_bytes(16);
    $encrypted = openssl_encrypt(
        $data,
        'AES-256-CBC',
        $key,
        0,
        $iv
    );
    return base64_encode($iv . $encrypted);
}

function wpfs_decrypt($data) {
    $key = defined('WPFS_ENCRYPTION_KEY')
           ? WPFS_ENCRYPTION_KEY
           : AUTH_KEY;
    $data = base64_decode($data);
    $iv = substr($data, 0, 16);
    $encrypted = substr($data, 16);
    return openssl_decrypt(
        $encrypted,
        'AES-256-CBC',
        $key,
        0,
        $iv
    );
}

Backup Security

  • Encrypt database backups
  • Store backups off-server
  • Test restoration regularly
  • Secure backup credentials separately

Monitoring and Auditing

  • Enable MySQL general log (temporarily)
  • Monitor failed connection attempts
  • Track schema changes
  • Audit data modifications

Conclusion

Database security requires multiple layers: unique table prefixes, prepared statements, proper permissions, encrypted connections, and regular backups. Never trust user input in database queries.

Share:
S
Written by Sarah Chen

WP Folder Shield Team

Related Articles

WordPress Cloaking Attack: When Google Sees Different Content Than Visitors
WordPress Cloaking Attack: When Google Sees Different Content Than Visitors

Cloaking attacks show different content to search engines than to human visitors. Learn how hackers...

January 14, 2026
SSL Certificates and HTTPS: Why Your WordPress Site Needs Them
SSL Certificates and HTTPS: Why Your WordPress Site Needs Them

SSL certificates encrypt data between your website and visitors. Learn why HTTPS is essential for...

December 26, 2025
Securing the WordPress wp-config.php File
Securing the WordPress wp-config.php File

The wp-config.php file contains your most sensitive WordPress settings. Learn how to protect this...

December 20, 2025

Ready to Secure Your WordPress Site?

Get complete protection with WP Folder Shield.

Get Started