MySQL Security Best Practices
MySQL Security Best Practices
The MySQL database has become the world's most popular open source database because of its consistent fast performance, high reliability and ease of use. MySQL is used on every continent yes, even in Antarctica! by individuals, Web developers, as well as many of the world's largest and fastest-growing organizations such as industry leaders Yahoo!, Alcatel-Lucent, Google, Nokia, YouTube and others to save time and money powering their high-volume websites, business-critical systems, and packaged software. As most products do, MySQL comes "ready-to-work" out of the box. Usually, security is not a major consideration when installing this kind of product. Often, the most important issue is to get it up and running as quickly as possible so that the organization can benefit. This document is intended as a quick security manual to help you bring an installed MySQL database server into conformity with best security practices.
Syntax explanation
This paper contains code examples that can either be executed in the operation system console, sent to the database via the MySQL console or added to configuration files. Code snippets are denoted by a gray background. Please refer to the surrounding context for more precise instructions.
Green SQL
GreenSQL is an Open Source Database Firewall created under a GPL license. It works as a reverse proxy and protects your database from numerous kinds of attacks that target database servers and the sensitive data that they store. GreenSQL was originally created with MySQL in mind. Following GreenSQL's wide acceptance, support for other database engines was added. Because of its database orientation, GreenSQL defends your data at the very point at which other types of protection products often fail preventing your data's destruction or leakage just before it happens.
Install Antivirus and Antispam software Configure the operating systems firewall
Consider the safety of your server's physical location Install the services you intend the machine to run Harden the production server and services Disable unnecessary services Follow services vendors recommendations regarding patches and updates needed for the safe and secure operation of their services
The file is located in the "C:\Program Files\MySQL\MySQL Server 5.1" directory on the Windows operating system or "/etc/my.cnf" or "/etc/mysql/my.cnf" on Linux. This line disables the initiation of networking during MySQL startup. Please note that a local connection can still be established to the MySQL server. Another possible solution is to force MySQL to listen only to the localhost by adding the following line in the [mysqld] section of my.cnf
bind-address=127.0.0.1
You may not be willing to disable network access to your database server if users in your organization connect to the server from their machines or the web server installed on a different machine. In that case, the following restrictive grant syntax should be considered:
mysql> GRANT SELECT, INSERT ON mydb.* TO 'someuser'@'somehost';
Or even simpler:
mysql> SELECT load_file("/etc/passwd")
To disable the usage of the "LOCAL INFILE" command, the following parameter should be added in the [mysqld] section of the MySQL configuration file.
set-variable=local-infile=0
The default administrator username on the MySQL server is "root". Hackers often attempt to gain access to its permissions. To make this task harder, rename "root" to something else and provide it with a long, complex alphanumeric password. To rename the administrators username, use the rename command in the MySQL console:
mysql> RENAME USER root TO new_user
The MySQL "RENAME USER" command first appeared in MySQL version 5.0.2. If you use an older version of MySQL, you can use other commands to rename a user:
mysql> use mysql; mysql> update user set user="new_user" where user="root"; mysql> flush privileges;
In a secure system, no lines should be echoed back. Another way to do the same:
mysql> SHOW GRANTS FOR ''@'localhost'; mysql> SHOW GRANTS FOR ''@'myhost';
If the grants exist, then anybody can access the database and at least use the default database "test". Check this with:
shell> mysql -u blablabla
The MySQL "DROP USER" command is supported starting with MySQL version 5.0. If you use an older version of MySQL, you can remove the account as follows:
mysql> use mysql; mysql> DELETE FROM user WHERE user=""; mysql> flush privileges;
A very common database security recommendation is to lower the permissions given to various parties. MySQL is no different. Typically, when developers work, they use the system's maximum permission and give less consideration to permission principles than we might expect. This practice can expose the database to significant risk. * Any new MySQL 5.x installation already installed using the correct security measures. To protect your database, make sure that the file directory in which the MySQL database is actually stored is owned by the user mysql and the group mysql.
shell>ls -l /var/lib/mysql
In addition, ensure that only the user "mysql" and "root" have access to the directory /var/lib/mysql. The mysql binaries, which reside under the /usr/bin/ directory, should be owned by root or the specific system mysql user. Other users should not have write access to these files.
shell>ls -l /usr/bin/my*
[Identify users]
mysql> select * from users;
The above statement has to be executed for each user ! Note that only users who really need root privileges should be granted them. Another interesting privilege is SHOW DATABASES. By default, the command can be used by everyone having access to the MySQL prompt. They can use it to gather information (e.g., getting database names) before attacking the database by, for instance, stealing the data. To prevent this, it is recommended that you follow the procedures described below.
Add --skip-show-database to the startup script of MySQL or add it to the MySQL configuration file Grant the SHOW DATABASES privilege only to the users you want to use this command
To disable the usage of the SHOW DATABASES command, the following parameter should be added in the [mysqld] section of the /etc/my.cnf:
[mysqld] skip-show-database
9. Enable Logging
If your database server does not execute many queries, it is recommended that you enable transaction logging, by adding the following line to [mysqld] section of the /etc/my.cnf file:
[mysqld] log =/var/log/mylogfile
This is not recommended for heavy production MySQL servers because it causes high overhead on the server. In addition, verify that only the root and mysql ids have access to these logfiles (at least write access). Error log Ensure only root and mysql have access to the logfile hostname.err. The file is stored in the mysql data directory. This file contains very sensitive information such as passwords, addresses, table names, stored procedure names and code parts. It can be used for information gathering, and in some cases, can provide the attacker with the information needed to exploit the database, the machine on which the database is installed, or the data inside it. MySQL log Ensure only root and mysql have access to the logfile *logfileXY. The file is stored in the mysql data directory.
In addition, to make the use of the database administrative tools convenient, the following parameter should be changed in the [client] section of MySQL configuration file:
[client] socket = /chroot/mysql/tmp/mysql.sock
Thanks to that line of code, there will be no need to supply the mysql, mysqladmin, mysqldump etc. commands with the --socket=/chroot/mysql/tmp/mysql.sock parameter every time these tools are run.
We should remove the content of the MySQL history file (~/.mysql_history), where all executed SQL commands are stored (especially passwords, which are stored as plain text):
cat /dev/null > ~/.mysql_history