Secure the future of MySQL. Sign this open letter

Hardening MySQL: Practical Security Strategies for DBAs

MySQL Security Best Practices: A Practical Guide for Locking Down Your Database

Introduction

MySQL runs just about everywhere. I’ve seen it behind small personal projects, internal tools, SaaS platforms, and large enterprise systems handling serious transaction volume. When your database sits at the center of everything, it becomes part of your security perimeter whether you planned it that way or not. And that makes it a target.

Securing MySQL isn’t about flipping one magical setting and calling it done. It’s about layers. Tight access control. Encrypted connections. Clear visibility into what’s happening on the server. And operational discipline that doesn’t drift over time.

In this guide, I’m going to walk through practical MySQL security best practices that you can apply right away. These are the kinds of checks and hardening steps that reduce real risk in real environments, and help build a database platform that stays resilient under pressure.


1. Principle of Least Privilege

One of the most common security mistakes is over-granting privileges. Applications and users should have only the permissions they absolutely need.

Bad Practice

sql
GRANT ALL PRIVILEGES ON *.* TO 'appuser'@'10.%';

Better Approach

sql
GRANT SELECT, INSERT, UPDATE ON appdb.* TO 'appuser'@'10.%';

Recommendations

  • Avoid global privileges unless absolutely required
  • Restrict users by host whenever possible
  • Separate admin accounts from application accounts
  • Use different credentials for read-only vs write operations

Audit Existing Privileges

sql
SELECT user, host, Select_priv, Insert_priv, Update_priv, Delete_priv
FROM mysql.user;

2. Strong Authentication & Password Policies

Weak credentials remain one of the easiest attack vectors.

Enable Password Validation

component_validate_password is MySQL’s modern password policy engine. Think of it as a gatekeeper for credential quality. Every time someone tries to set or change a password, it checks whether that password meets your defined security standards before letting it in.

It replaces the older validate_password plugin with a component-based architecture that is more flexible and better aligned with MySQL 8.x design.

sql
INSTALL COMPONENT 'file://component_validate_password';

What It Does

When enabled, it enforces rules such as:

  • Minimum password length
  • Required mix of character types
  • Dictionary file checks
  • Strength scoring

If a password fails policy, the statement is rejected before the credential is stored.

Why It Matters

Weak passwords remain one of the most common entry points in database breaches. This component reduces risk by enforcing baseline credential hygiene automatically, instead of relying on developer discipline.

  • Minimum length: 14+ characters
  • Require mixed case, numbers, and symbols
  • Enable dictionary checks
  • Enable username checks

Remove Anonymous Accounts

Find Anonymous Users

Anonymous users have an empty User field.

sql
SELECT user, host FROM mysql.user WHERE user='';

If you see rows returned, those are anonymous accounts.

Drop Anonymous Users

In modern MySQL versions:

sql
DROP USER ''@'localhost';
DROP USER ''@'%';

Adjust the Host value based on what your query returned.

Why This Matters

Anonymous users:

  • Allow login without credentials
  • May have default privileges in some distributions
  • Increase the attack surface unnecessarily

In hardened environments, there should be zero accounts with an empty username. Every identity should be explicit, accountable, and least-privileged.

3. Encryption Everywhere

Encryption protects data both in transit and at rest.

Enable Transparent Data Encryption (TDE)

See my January 13 post for a deep dive into Transparent Data Encryption: Configuring the Component Keyring in Percona Server and PXC 8.4

Enable TLS for Connections

sql
require_secure_transport=ON

Verify SSL Usage

sql
SHOW STATUS LIKE 'Ssl_cipher';

Encryption Areas to Consider

  • Client-server connections
  • Replication channels
  • Backups and snapshot storage
  • Disk-level encryption

4. Patch Management & Version Hygiene

Running outdated MySQL versions is equivalent to leaving known vulnerabilities exposed.

Maintenance Strategy

  • Track vendor security advisories
  • Apply minor updates regularly
  • Test patches in staging before production rollout
  • Avoid unsupported MySQL versions

Check Version

sql
SELECT VERSION();

5. Logging, Auditing, and Monitoring

Security without visibility is blind defense, enable Audit Logging.

1. audit_log Plugin (Legacy Model)

Installation

sql
INSTALL PLUGIN audit_log SONAME 'audit_log.so';

Verify

sql
SHOW PLUGINS LIKE 'audit%';

2. audit_log_filter Component (Modern Model)

Introduced in MySQL 8 to provide a more flexible and granular alternative to the older plugin model.

Installation

sql
INSTALL COMPONENT 'file://component_audit_log_filter';

Verify

sql
SELECT * FROM mysql.component;

Architecture Difference

Instead of a single global policy, you create:

  • Filters (define what to log)
  • Users assigned to filters

It’s granular and rule-driven.

Auditing Key Events

  • Failed logins
  • Privilege changes
  • Schema modifications
  • Unusual query activity

References:

  1. Audit Log Filter Component
  2. Audit Log Filters Part II

Useful Metrics

sql
SHOW GLOBAL STATUS LIKE 'Aborted_connects';
SHOW GLOBAL STATUS LIKE 'Connections';

6. Secure Configuration Hardening

A secure baseline configuration reduces risk from common attack patterns.

ini
local_infile=OFF
secure_file_priv=/var/lib/mysql-files
sql_mode="STRICT_ALL_TABLES"
secure-log-path=/var/log/mysql

Why These Matter

  • Prevent arbitrary file imports
  • Reduce filesystem abuse
  • Restrict data export/import locations

7. Backup Security

Backups often contain everything an attacker wants.

Backup Best Practices

  • Encrypt backups
  • Restrict filesystem permissions
  • Store offsite copies securely
  • Rotate backup credentials
  • Verify restore procedures regularly

Example Permission Check

bash
ls -l /backup/mysql

8. Replication & Cluster Security

Replication is not just a data distribution feature. It is a persistent, privileged communication channel between servers. If misconfigured, it can become a lateral movement pathway inside your infrastructure. Treat every replication link as a trusted but tightly controlled corridor.

Principle: Replication Is a Privileged Service Account

Replication users require elevated capabilities. They must be isolated, tightly scoped, and monitored like any other service identity.

Secure Replication Users

sql
CREATE USER 'repl'@'10.%'
  IDENTIFIED BY 'strongpassword'
  REQUIRE SSL;

GRANT REPLICATION REPLICA ON *.* TO 'repl'@'10.%';

Hardening considerations:

  • Restrict host patterns as narrowly as possible. Avoid % whenever feasible.
  • Require SSL or X.509 certificate authentication.
  • Enforce strong password policies or use a secrets manager.
  • Disable interactive login capability if applicable.

Encrypt Replication Traffic

Replication traffic may include sensitive row data, DDL statements, and metadata. Always encrypt it.

At minimum:

  • Enable require_secure_transport=ON
  • Configure TLS certificates on source and replica
  • Set replication channel to use SSL:
sql
CHANGE REPLICATION SOURCE TO
  SOURCE_SSL=1,
  SOURCE_SSL_CA='/path/ca.pem',
  SOURCE_SSL_CERT='/path/client-cert.pem',
  SOURCE_SSL_KEY='/path/client-key.pem';

For MySQL Group Replication or InnoDB Cluster:

  • Enable group communication SSL
  • Validate certificate identity
  • Use dedicated replication networks

Binary Log and Relay Log Protection

Replication relies on binary logs. Protect them.

  • Set binlog_encryption=ON
  • Set relay_log_info_repository=TABLE
  • Restrict filesystem access to log directories
  • Monitor log retention policies

Compromised binary logs can reveal historical data changes.

9. Continuous Security Reviews

Security is not a one-time checklist. Regular audits help catch configuration drift and evolving threats.

Suggested Review Cadence

  • Weekly: failed login review
  • Monthly: privilege audits
  • Quarterly: configuration review
  • Semiannually: full security assessment

Security Checklist Summary

AreaKey Action
Access ControlLeast privilege grants
AuthenticationStrong password policies
EncryptionTLS + encrypted storage
UpdatesRegular patching
MonitoringAudit logging enabled
ConfigurationHarden defaults
BackupsEncrypt and protect
ReplicationSecure replication users

Final Thoughts

Strong MySQL security doesn’t come from one feature or one tool. It comes from layers working together. Hardened configuration. Tight, intentional privilege design. Encryption everywhere it makes sense. And monitoring that actually gets reviewed instead of just written to disk.

In my experience, the strongest environments aren’t the ones trying to be unbreakable. They’re the ones built to detect, contain, and respond. Every layer should either reduce blast radius or increase visibility. If an attacker gets through one control, the next one slows them down. And while they’re slowing down, your logging and monitoring should already be telling you something isn’t right.

That’s what a mature security posture looks like in practice.

Wayne Leutwyler

When I’m not working with MySQL or other Open-source software packages. I like to do woodworking, 3D design and Printing, listening to all forms of Metal music and electronic projects with Raspberry PI, Arduino. Wayne lives in Powell Ohio, with his wife, daughter, 6 cats and 2 dogs.

See all posts by Wayne Leutwyler »

Discussion

We invite you to our forum for discussion. You are welcome to use the widget below.

✎ Edit this page on GitHub