Yes, you read this correctly: because the MySQL client is insecure and allows running arbitrary commands, and because mysqldump blindly trusts the server it is dumping from, a hostile MySQL Server on which mysqldump is executed could trigger arbitrary command execution (also known as a remote code execution). This post raises awareness on this vulnerability and shows how a secure MySQL client makes things harder to exploit.
This post is a follow-up post on my previous post 17 Years of Insecure MySQL Client. I ended this post with a cryptic sentence: “there is more to say about this, but I will stop here for now”. I also used this sentence in another post, Fun with InnoDB Persistent Statistics, where I was setting the stage for the post about the CREATE TABLE of Death.
This post is written in the context of my work on MySQL at Aiven: check our careers page or blog to know more about us.
A few months ago, via the Aiven Bug Bounty Program, it came to our attention that the Migration Tool we provide our customer to migrate to Aiven for MySQL was vulnerable to Remote Code Execution. Part of the exploit was leveraging the insecure MySQL client. The way we blocked this is described in my previous post. This post gives more information about the exploit.
A few words about this exploit: it was not as scary as it looked (none of Aiven's Core or Management Infrastructure was affected). Aiven's Service Architecture ensures customers are isolated, which includes migrations. So, the exploit could have allowed someone to run arbitrary commands on their own isolated infrastructure, not on the Aiven Core or Management Infrastructure, or any other customer service.
I am not explaining in detail how to exploit this. It is still a recent vulnerability and I think it is too early to give details. When this came to my attention, I opened a security / private bug to Oracle in the MySQL Bug System (it is Bug #114189, opened on March 1, 2024), and I later shared details with Percona and MariaDB (respectively on March 12 and on April 4). At the same time, I opened another bug references in my previous post: Bug #114328 - Please provide a "secure mode" for the MySQL Client. Since then, MariaDB came-up with a clever solution, more about this later in this post. In summary, the vulnerability is as follows.
mysqldump blindly trusting the dumped server
allows a hostile server to inject commands in the dump,
and this, combined with the insecure MySQL client,
allows arbitrary command execution and more…
So, if you need to run a mysqldump on an instance you do not control, be careful ! I think there is not much you can do to prevent a hostile server from injecting something in the dump (I think it is futile to try “sanitizing” the output of mysqldump), but you can be careful in the way you load the dump (using the solution described in my previous post).
And this is not only about arbitrary code execution (did you notice the “and more…” above ?). There is nothing that prevents a hostile MySQL server from injecting SQL commands in a dump. These commands could create a new user and grant it full privileges, could change the configuration of your MySQL server, or could even phone home and leak a few bytes via the arguments of a well-crafted CHANGE REPLICATION SOURCE TO. If you load a dump as the root MySQL user, you expose yourself to all these risks. So be smart in choosing the user for loading a dump (my advice would be a user only having full rights in a single schema, nothing more).
When I opened Bug #114189 (private bug), I reported the vulnerability in mysqldump. In addition to having a secure mode in the MySQL Client, I thought the mysqldump utility could be more resilient to such an attack, but I did not know how. This is where MariaDB thought of a clever solution. They introduced a Sandbox Mode in their client, which is basically the secure mode I want in the MySQL client, and their mariadb-dump utility tells the MariaDB Client to run in sandbox mode. This prevents a dump made with a recent mariadb-dump to run arbitrary commands via the MariaDB Client, but this breaks the compatibility of the new mariadb-dump with old MariaDB / MySQL clients. This is what is described in their post MariaDB Dump File Compatibility Change. Also in this post, there is a link to MDEV-33727 describing this work. I find it interesting that this MDEV was created on March 19, so before I notified MariaDB about the vulnerability. This made me think it might have been more widely known than I thought. I did some investigations, and there is more to say about this, but I will stop here for now. ;-)
That is it for now. I hope I have convinced you to be careful with the insecure MySQL client. An option to have a more secure client in non-interactive mode, mentioned as a comment in my previous post by Evan Elias, is to use the --binary-mode argument (unclear if this was designed for this or is an accidental side-effect). And hopefully, we will get a more secure client soon (if you think this is important, you can click the “Affects Me” or the “Subscribe” button in Bug #14328: Please provide a "secure mode" for the MySQL Client).
I should note, in the last couple of days, MariaDB developers have come up with a way to keep sandbox mode and maintain compatibility. This should be coming very soon.
ReplyDeletecould you tell how they will do it?
Delete