The issueOn 12 September 2016 (three days ago) a MySQL security vulnerability was announced. The CVE id is CVE-2016-6662.
There are 3 claims:
- By setting malloc-lib in the configuration file access to an OS root shell can be gained.
- By using the general log a configuration file can be written in any place which is writable for the OS mysql user.
- By using SELECT...INTO DUMPFILE... it is possible to elevate privileges from a database user with the FILE privilege to any database account including root.
How it is supposed to be used
- Find an SQL Injection in a website or otherwise gain access to a MySQL account.
- Now create a trigger file (requires FILE privilege)
- Now in the trigger or otherwise use SET GLOBAL general_log_file etc to create a my.cnf in the datadir with the correct privileges. Directly using SELECT...INTO DUMPFILE...won't work as that would result in the wrong permissions, which would cause mysqld/mysqld_safe to ignore that file.
- Now wait someone/something to restart MySQL (upgrade, daily cold backup, etc) and a shell will be available on a port number and IP address chosen by the attacker.
How it is fixedThe document claims "Official patches for the vulnerability are not available at this time for Oracle MySQL server. ", but that isn't true.
From the 5.7.15 release notes:
mysqld_safe attempted to read
my.cnfin the data directory, although that is no longer a standard option file location. (Bug #24482156)
For mysqld_safe, the argument to
--malloc-libnow must be one of the directories
/usr/lib/x86_64-linux-gnu. In addition, the
--mysqld-versionoptions can be used only on the command line and not in an option file. (Bug #24464380)
It was possible to write log files ending with
.cnfthat later could be parsed as option files. The general query log and slow query log can no longer be written to a file ending with
.cnf. (Bug #24388753)
So 2 out of the 3 vulnerabilities are patched. So the obvious advice is to upgrade.
Further steps to takeBut there are more things you can do to further secure your setup.
Check if your my.cnf file(s) are writable for the mysql user/etc/my.cnf, /etc/mysql/my.cnf /etc/mysql/my.cnf.d/* should NOT be writable for the mysql user. Make sure these are owned by root and mode 644.
Put an empty my.cnf in your datadir and make sure it has the above mentioned privileges. The vulnerability document also mentions a .my.cnf in the datadir, so also make that an empty file.
Review accounts with the FILE privilege:Run this query and drop accounts or revoke the file privilege from them if they don't really need it.
SELECT GRANTEE FROM INFORMATION_SCHEMA.USER_PRIVILEGES WHERE PRIVILEGE_TYPE='FILE';
Isolate servicesDon't run all services on one machine. Isolate services from each other. So put the webserver and database server on separate (virtual) machines or containers.
Use a firewall. If the database suddenly starts to listen on a weird port the attacker should not be able to connect to it. This can be a host based firewall like iptables and a network device. Yes an IDS might be able to detect the network shell, but running an IDS/IPS needs serious amount of time and doesn't give any guarantees.
Prepare for the next vulnerabilityThis is not only for MySQL, but also for other parts of your stack (OS, webserver, etc).
Make sure the configuration is secured properly for each service. A helpful resource here are the benchmark documents from the Center for Internet Security.