The Easy MySQL Security In-Depth Guide to Best Practices
Tags: mysql, database, tutorial, security
Published: 2023-11-07 08:22:39

The digital realm is a bit like the Wild West, with data as the new gold rush. In this modern age, MySQL stands tall among databases, like a shimmering treasure in a world of bandits. But there's a catch---those bandits are cyber threats, and they're after your valuable data. So, MySQL security is important more than ever.

According to IBM's Cost of Data Breach Report for 2023, the outlook is getting scarier. [The global average cost of a data breach is a whopping $4.45 million](https://www.ibm.com/reports/data-breach). That's a treasure trove for the wrong kind of folks. But there's more to that number. It's a 15% increase for over 3 years.

And MySQL consistently ranks high in popularity. With that in mind, it's like hanging a neon sign on your data saying, "Come and get it." It's among the top three in the [dbEngines ranking](https://db-engines.com/en/ranking). And among the favorites in the [StackOverflow Developer Survey for 2023](https://survey.stackoverflow.co/2023/#section-most-popular-technologies-databases).

Being the guardian of your database's security might sound a bit scary. It's like watching over a precious gem in a museum. But don't worry, it's not an impossible feat. With the right tools and a little know-how, it's like setting up a security system to protect your treasure.

So, in this exciting guide, we'll journey through the treacherous world of common MySQL security threats. We'll unravel the secrets of MySQL security configuration. And then, provide a checklist of best practices. That's like building a fortress around your data. Plus, we'll introduce you to a trusty security companion, the hero of our story.

Let's dive in and secure that precious MySQL treasure!

## Discussion Key Points to Secure MySQL

First, let me give you the outline of our discussion:

-   [Common MySQL Security Threats](#common-mysql-security-threats)

-   [MySQL Security Configuration](#mysql-security-configuration)

-   [MySQL Security Best Practices](#mysql-security-best-practices)

-   [Implementing MySQL Security Using a GUI Tool](#implementing-mysql-security-using-a-gui-tool)

## Common MySQL Security Threats

Before you secure your MySQL database, you should know what you need to look out for.

So, let's break down the common MySQL security threats in everyday language. These threats may apply whether your MySQL is on-premises or in the cloud.

### Mismanagement of Account Access: The Open Front Door

Ever had that feeling of leaving your front door wide open? Well, mismanaging account access in MySQL is pretty much the same. It's like giving the keys to your house to a stranger. You wouldn't do that, right?

In MySQL, if you don't control who can access your data, you're essentially inviting anyone in. Let's say you've got a database for customer information, and an employee who shouldn't have access to it suddenly can. That's a mismanagement of account access. It's like leaving your customer data out in the open for anyone to take, and that's a big no-no.

How to Prevent:

To avoid this, always review and manage user access permissions carefully. Regularly audit and update who can access your MySQL database. Think of it like periodically changing the locks on your front door to keep the wrong folks out.

### Weak Passwords: The "123456" Lock Code

Now, think about your front door lock. If your lock code is "123456," it's like putting a sign on your door saying, "Welcome, feel free to come in!" Weak passwords are like that code. If your database has easy-to-guess passwords, it's like an open invitation to hackers.

Say you've set your MySQL password as "password123" or "p@s$w0rd1". That's as secure as a cardboard lock on a treasure chest. It's crucial to use strong, unique passwords to protect your data.

How to Prevent:

Use strong, complex passwords. A mix of upper- and lower-case letters, numbers, and special characters is your best bet. It's like having a combination lock on your door that's a million digits long.

### DDoS Attacks: The Cyber Hurricane

Imagine you've fortified your home, but then a hurricane hits. [DDoS](https://en.wikipedia.org/wiki/Denial-of-service_attack) attacks are like cyber hurricanes. They flood your server with traffic using fake queries, making it crash. It's as if a tidal wave is smashing against your defenses. Your website or app becomes unusable, and that's a real headache.

For example, a popular e-commerce site suddenly gets hit with a massive surge in traffic. It's not genuine customers; it's an army of bots overwhelming the server. The site crashes, and customers can't make purchases. That's the havoc of a DDoS attack.

How to Prevent:

Use a [Web Application Firewall (WAF)](https://www.cloudflare.com/learning/ddos/glossary/web-application-firewall-waf/) and DDoS mitigation services to filter out malicious traffic. It's like having a force field around your online fortress to keep the digital storm at bay.

### SQL Injection Attacks: The Sneaky Spy

SQL injection attacks are like having a sneaky spy in your midst. It happens when someone enters malicious code into your application, and it can access or modify your database. It's like giving a thief the secret combination to your safe.

Suppose you have an online login form where users enter their information. A hacker might input code that tricks the system into revealing sensitive data, like passwords or customer records. Or worse, it destroys everything. It's a covert way for them to gain unauthorized access.

How to Prevent:

Sanitize inputs and use parameterized queries. Make sure your application doesn't blindly trust user input, and instead, validate and clean it. It's like screening everyone who enters your secret club to keep the sneaky spies out.

#### Sample SQL Injection Code (Don't Use This!):

Here's a Python REST API method with a MySQL query that's open to SQL injection:

```
def login(username, password):
query = f"SELECT * FROM users WHERE username = '{username}' AND password = '{password}'"
# Execute the query and check if the user is authenticated
...
# DON'T DO THIS! It's open to SQL injection. An attacker could input malicious code as the 'password' parameter.\
```

See how the 'password' parameter isn't sanitized? An attacker could input something like '; DROP TABLE users;-- as the password and wreak havoc. Always use parameterized queries to prevent this!

### Privilege Escalation: Climbing the Ladder

You know how some folks try to climb the ladder, aiming for a higher position in an organization? Privilege escalation is like that but in the MySQL world. It's when someone with limited access tries to reach for more power within your database.

Imagine you have a user with only "read" access to your database. But somehow, they find a way to change their access to "admin." That's privilege escalation.

How to Prevent:

Preventing privilege escalation is a bit like controlling who gets the keys to different rooms in your house. Be careful when giving privileges, and make sure users only get access to what they need. No room for climbing the ladder.

### Insecure Connections: Doors Have Ears, Windows Have Eyes

Insecure connections are like inviting nosy neighbors to spy on you. They can hear your private conversations and see what's happening from your window. In MySQL, it's when data travels between your application and the database without encryption.

For example, you provided your credit card number on an unsecured website. So, communication from your web app to your MySQL has no encryption. Any clever attacker can "sniff" the wires with tools and see your credit card number.

How to Prevent:

To prevent insecure connections is like sending your secrets through a locked, secret tunnel. Use SSL or TLS encryption for connections between your application and MySQL. It's like putting your data in a secure, locked box.

### Unpatched Vulnerabilities: Using an Armor with Holes

Think of unpatched vulnerabilities as having holes in your armor. It's like fighting a dragon without a complete set of armor. In MySQL, it happens when you don't update your server with the latest security patches. Attackers will take advantage of buffer overflows and other vulnerabilities.

How to Prevent:

Preventing unpatched vulnerabilities is like maintaining your armor. Keep MySQL up to date with the latest patches and security updates. It's like reinforcing your fortress to withstand new threats.

### Remote Preauth User Enumeration: The Secret Handshake

Picture this: You're at a secret club, and to enter, you need to do a specific handshake. Remote preauth user enumeration is like knowing that secret handshake. It's when an attacker can figure out which user accounts exist on your system, even before they've authenticated.

For instance, let's say your MySQL database has a list of users. An attacker discovers a way to check if a specific user account is valid without logging in. So, this is a security hole because now they can focus on breaking into known accounts. Attackers can use brute-forcing passwords or exploit privileges.

How to Prevent:

Apply security patches from MySQL as long as they become available. Also, limit the number of login attempts. Then, use strong passwords for database users. Furthermore, restrict remote access to the database or use a firewall.

Now that you're aware of MySQL threats, it's time to put a secret tunnel with locked doors, so to speak.

## MySQL Security Configuration

This section will cover MySQL user access, encryption, and logging.

Let's begin.

### MySQL Security User Access Control

Follow the principle of least privilege, where you allow users to access what they only need. If someone only needs to read reports, provide read-only access. Better yet, if users will only interact with data through an app, do not give them ANY access at all. Though this requires more work for your app, but the security headaches are less. You will need a middle tier where the app accesses APIs to read and write data. That's what I did in my experience.

If ever you need to provide access to a select few, MySQL offers several ways that will make it secure. Below are some tips about passwords and limited access.

#### Use Password Management Options

Never settle for a user access like this:

```
mysql> CREATE USER 'edwin'@'localhost' IDENTIFIED BY 'password';\
```

Instead, add options to secure the account, like using failed login attempts and more. Here's an example:

```
mysql> CREATE USER 'edwin'@'localhost'
IDENTIFIED WITH caching_sha2_password BY 'new_strong_password'
PASSWORD EXPIRE INTERVAL 90 DAY
FAILED_LOGIN_ATTEMPTS 3 PASSWORD_LOCK_TIME 2;\
```

The extra options here are:

* IDENTIFIED WITH caching_sha2_password -- This will authenticate the user using [caching SHA-2 pluggable authentication](https://dev.mysql.com/doc/refman/8.0/en/caching-sha2-pluggable-authentication.html).

* PASSWORD EXPIRE INTERVAL 90 DAYS -- The user needs to change passwords every 90 days.

* FAILED_LOGIN_ATTEMPTS 3 -- With this, the user can only make 3 attempts to enter the correct password.

* PASSWORD_LOCK_TIME 2 -- After 3 failed attempts, the account will be locked out for 2 days.

There are more options available, like multi-factor authentication. For more details, consult the [official documentation](https://dev.mysql.com/doc/refman/8.0/en/create-user.html).

You can also use global system variables to control password management. Check it out [here](https://dev.mysql.com/doc/mysql-secure-deployment-guide/8.0/en/secure-deployment-user-accounts.html).

#### Restrict Access to Specific IP Address

Restricting access from a specific machine will make it harder to access your MySQL server. You can use the GRANT command to do this. Here's an example:

```
mysql> CREATE USER 'edwin'@'192.89.102.0'
IDENTIFIED WITH caching_sha2_password BY 'new_strong_password'
PASSWORD EXPIRE INTERVAL 90 DAY
FAILED_LOGIN_ATTEMPTS 3 PASSWORD_LOCK_TIME 2;

mysql> GRANT ALL ON sakila.* TO 'edwin'@'192.89.102.0'\
```

This will create the user using password options and limited to access MySQL from 192.89.102.0. It can also read and write to the sakila database only. Any other database is inaccessible.

#### Restrict Database Permissions

We already have an example of limiting to only one database. In this subsection, you will learn more about database permissions. A user who does read and write will have SELECT, INSERT, UPDATE, and DELETE permissions. If a user only needs to read report data, you can grant a limited access like this:

```
mysql> GRANT SELECT on sakila.* TO 'edwin'@'localhost';\
```

The command above will only allow read-only access to sakila database. This includes all database objects within sakila.

If you want to limit it further to a specific table, you can do so by specifying them. Instead of using *, use a specific table name like the one below:

```
mysql> GRANT SELECT ON sakila.film TO 'edwin'@'localhost';\
```

### Encrypted Connections

MySQL needs certificates and key files to use secured encrypted connections. It starts with setting up MySQL and using a certificate authority. You can check it out [here](https://dev.mysql.com/doc/mysql-secure-deployment-guide/8.0/en/secure-deployment-secure-connections.html).

Then, you can restrict a user to use encrypted connections upon creating the MySQL user account. The example below requires SSL when connecting to MySQL.

```
mysql> CREATE USER 'poknat'@'localhost' IDENTIFIED BY '1@Abe91-SEC' REQUIRE SSL;\
```

"REQUIRE SSL" are the magic keywords needed for encrypted connections. Connections will fail if a secured connection cannot be established. You can check the [MySQL documentation](https://dev.mysql.com/doc/refman/8.0/en/create-user.html#create-user-tls) for more options on encrypted connections.

### MySQL Security Auditing and Logging

MySQL security also involves checking the logs on what's happening on the server. The logs also tell who does what. So, this is a must.

Several logs in MySQL need checking from time to time. But for security purposes, you can start checking the logged connections and commands. You can find this in the MySQL general query log. From here, you can check for any suspicious activity. Look for unknown IP addresses and the commands they run.

The general query log is disabled by default. You can enable it using the system variables general_log, log_output, and general_log_file. Once enabled, you can check the log file specified in general_log_file. Or, if TABLE is your log_output destination, check the mysql.general_log table in your MySQL server.

For more information about MySQL logs, check out [this link](https://dev.mysql.com/doc/refman/5.7/en/server-logs.html).

### Regular Secured Backup and Disaster Recovery Plan

Let's face it. No matter how good your security is, someone can outsmart you and wreak havoc on your MySQL server. To prepare for that, you should have a disaster recovery plan and a regular, secured backup. This will allow you to recover faster from damages done to your MySQL server.

### Encrypted Data at Rest

You can also consider Transparent Data Encryption (TDE) to encrypt the physical files of your database and protect data at rest. [MySQL Enterprise offers TDE](https://www.mysql.com/products/enterprise/tde.html). Or if your MySQL server is in the cloud like [AWS](https://docs.aws.amazon.com/dms/latest/oracle-to-aurora-mysql-migration-playbook/chap-oracle-aurora-mysql.security.encryption.html#chap-oracle-aurora-mysql.security.encryption.mysql), it uses the AWS Key Management Service to perform the encryption.

By encrypting data at rest, you can make your database unreadable to anyone without the decryption key. So, in the event of theft, they cannot access your precious data.

## MySQL Security Best Practices

Safeguarding your MySQL database involves a checklist to fortify your defenses:

1.  Remove Default Accounts, Port Mappings, and Other Settings: Delete default accounts and unused configurations to prevent potential exploits.

2.  Restrict Remote Access: Limit access to authorized users or specific IP addresses. This will reduce the risk of unauthorized entry.

3.  Grant Users Only the Privileges They Need: Follow the principle of least privilege, granting users access only to necessary resources.

4.  Use Non-Root Accounts: Avoid using the root account for everyday operations. That will cut the impact of any accidental misuse or security breaches. Limit the use of the root account as much as possible. For example, logging into the database is only possible directly from the server--- locally or through a list of specific IPs. Never use the root account for daily operations if the work can be done under another account.

5.  Keep the Server Physically Secure: Ensure physical security measures for the server to prevent unauthorized access.

6.  Proper Auditing & Monitoring: Check and audit user activities and system behaviors regularly. So, you can detect and respond to potential security risks.

7.  Regular Security Assessments: Conduct periodic security assessments to identify and address vulnerabilities proactively.

8.  Strong Authentication Credentials and Encryption: Enforce strong authentication measures. Encrypt sensitive data both at rest and in transit.

These best practices are gems. Follow these to mitigate risks and ensure the integrity of your MySQL database.

## Implementing MySQL Security Using a GUI Tool

Most of what we did in the command line interface for security can be done in a GUI tool like dbForge Studio for MySQL.

For example, dbForge Studio for MySQL has the following:

* Security Manager: for managing user accounts and roles, including global and object privileges.
* Server Variables: to view all MySQL variables, including the general_log, log_output, and others.
* Session Manager: for viewing all users currently connected to your MySQL server.
* SQL window with code and object suggestions: for scripting your MySQL security tasks.

Take a look at the [Security Manager](https://www.devart.com/dbforge/mysql/studio/securitymanager.html) below where you can create users and maintain their password.

![Implementing MySQL security by maintaining user accounts using dbForge Studio for MySQL.](https://blog.devart.com/wp-content/uploads/2023/11/dbforge-security-manager-general.png)

And here's the tab for assigning Object Privileges.

![Assigning database permissions for a user using the Security Manager of dbForge Studio for MySQL.](https://blog.devart.com/wp-content/uploads/2023/11/dbforge-security-manager-object-privileges.png)

You can also use the Security Manager for encrypted connections in the SSL tab.

Meanwhile, you can use the Server Variables to view and set values to MySQL variables. For example, the screenshot below changes the log_output variable from FILE to TABLE.

![MySQL variables](https://blog.devart.com/wp-content/uploads/2023/11/dbforge-server-variables.png)

The changes will let you view the general query logs in a nice GUI interface. It will let you filter, sort, and more. So, if it's a very long list of rows, it's manageable.

![View the MySQL general query log from a table to manage logs for MySQL security.](https://blog.devart.com/wp-content/uploads/2023/11/dbforge-view-general-log-table-viewer.png)

You can also view the long text within the argument column using the Data Viewer.

Then, here's the Session Manager with the current connections in my own MySQL server.

![MySQL Session Manager](https://blog.devart.com/wp-content/uploads/2023/11/dbforge-session-manager.png)

And finally, here's the SQL Window showing some code suggestions to complete the statement.

![Using the SQL Window for coding and scripting in dbForge Studio for MySQL.](https://blog.devart.com/wp-content/uploads/2023/11/dbforge-sql-window.png)

### Success Stories About dbForge Studio for MySQL

Let's have a few success stories from using dbForge Studio for MySQL.

* Empower, LLC says it's a "fantastic tool" for ensuring MySQL database security. View the success story [here](https://www.devart.com/success-story/empower.html).

* One of the features Goran Pavkovic finds exciting in dbForge Studio for MySQL is server administration. Find his story from [here](https://www.devart.com/success-story/goran-pavkovic.html).

So, if you find dbForge Studio for MySQL exciting, why not download a copy from [here](https://www.devart.com/dbforge/mysql/studio/)?

## Takeaways

Throughout this in-depth guide, we've explored crucial elements of MySQL security:

* Understanding the importance of MySQL security in the face of evolving threats.

* Identifying common threats such as mismanaged account access and SQL injection attacks.

* Configuring MySQL securely with stringent access controls, encryption, and auditing.

* Embracing best practices, including limiting user privileges and conducting regular security assessments.

* Using a GUI tool like dbForge Studio for MySQL. This tool improves productivity in configuring MySQL security.

Becoming a MySQL security expert is a journey, not a sprint. It won't be flawless from day one. Starting with the basics laid out here is your first step.

So, use the security measures discussed in this guide. Regularly reassess and enhance your security protocols. Adapt to new threats and changes in the technological landscape. Stay vigilant, stay updated, and commit to building a resilient security fortress for your MySQL database.