Bug #114328 Please provide a "secure mode" for the MySQL Client.
Submitted: 12 Mar 19:45 Modified: 30 Oct 18:38
Reporter: Jean-François Gagné Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: Command-line Clients Severity:S4 (Feature request)
Version:8.3.0, 8.0.36 OS:Any
Assigned to: CPU Architecture:Any

[12 Mar 19:45] Jean-François Gagné
Description:
Hi,

it is relatively easy to break-out of a MySQL client to execute arbitrary commands in the "environment" where the cli is run (not on the server where mysqld is run), see How to repeat for examples.  This makes providing a restricted environment / shell with the MySQL client very complicated because smart users can break-out of the restricted environment.  It also makes executing SQL scripts potentially "dangerous" operations because such script can run arbitrary command.

Some Unix commands which have a "break-out" risk provide a "secure mode" where the "break-out" features are disabled.  An example is the LESSSECURE feature of less [1].

[1]: https://man7.org/linux/man-pages/man1/less.1.html

Please consider implementing a "secure mode" in the MySQL client to reduce exploits leveraging unsafe commands / features of the cli.

There is also an argument to be made that the MySQL client executing commands via arguments or stdout should be in secure mode by default (maybe only the interactive mode should be in unsafe mode by default).

Note: executing an untrusted mysqldump was already identified as a problem in 2007 (more than 16 years ago !) in Bug#26941.  I would claim that the general case of running an untrusted SQL script happens quite often: any schema upgrade script provided as part of a software upgrade (Wordpress, Graphana, ...) could qualify as such untrusted script.

Many thanks for looking into this,

Jean-François Gagné

How to repeat:
Below with MySQL 8.3.0, but the same applies to 8.0.36.

dbdeployer deploy single mysql_8.3.0

The "pager" command in interactive mode allows running arbitrary command (I was not able to use this in non-interactive mode).

rm -f a_file; ./use

mysql [localhost:8300] {msandbox} ((none)) > pager touch a_file
PAGER set to 'touch a_file'
mysql [localhost:8300] {msandbox} ((none)) > select 1;
1 row in set (0.01 sec)

mysql [localhost:8300] {msandbox} ((none)) > exit
Bye

ls -l a_file 
-rw-rw-r--. 1 jgagne jgagne 0 Mar 12 19:23 a_file

The "system" command, even in non-interactive mode, allows running arbitrary command.

f=a_file; rm -f $f; echo "system touch $f" | ./use; ls -l $f
-rw-rw-r--. 1 jgagne jgagne 0 Mar 12 19:23 a_file

Suggested fix:
Please consider implementing a "secure mode" in the MySQL client to reduce exploits leveraging unsafe commands / features of the cli.

There is also an argument to be made that the MySQL client executing commands via arguments or stdout should be in secure mode by default (maybe only the interactive mode should be in unsafe mode by default).
[13 Mar 5:57] MySQL Verification Team
Hello Jean-François,

Thank you for the feature request!

regards,
Umesh
[15 Mar 16:24] Jean-François Gagné
Until this is implemented, a solution can be found in below.

https://stackoverflow.com/questions/40958372/how-to-make-the-system-command-unavailable-in...
[19 Jun 17:47] Jean-François Gagné
An option to have a more secure client in non-interactive mode, mentioned as a comment [1] in my previous post by Evan Elias [2], is to use the --binary-mode argument [3] (unclear if this was designed for this or is an accidental side-effect; as this is a verified feature request, I assume it is accidental).

[1]: https://jfg-mysql.blogspot.com/2024/04/17-years-of-insecure-mysql-client.html?showComment=...

[2]: https://x.com/EvanElias

[3]: https://dev.mysql.com/doc/refman/8.0/en/mysql-command-options.html#option_mysql_binary-mod...
[30 Oct 18:38] Jean-François Gagné
This was "partially" fixed in 8.0.40, 8.4.3, and 9.1.0 by WL#16482.

Only partially, because the fix only implement disabling the "system" command.  According to below quote from the release notes, "pager", and other commands shared in a private comment, are still available.

Below a quote from 8.0.40 release notes [1]:

[1]: https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-40.html

> Added the --system-command option for the mysql client, which enables or disables the system client command.
>
> This option is enabled by default. To disable it, use --system-command=OFF or --skip-system-command, which causes the system command to be rejected with an error.