Security Advisory: `services.mysql` is configured with insecure authentication by default when used with `mysql` or `percona-server`

Summary

The NixOS module for MySQL services.mysql initializes the MySQL database in a way that allows local users (e.g. unprivileged web/CGI processes on the same host, but not remote users) to log in as the root user without a password when the service is used with mysql or percona-server.

Am I affected?

You’re impacted if:

  • you are using services.mysql with the mysql or percona-server package
  • you did not adjust MySQL authentication settings

You can confirm that you are impacted by executing the following command on the server running MySQL:

sudo -u nobody mysql -u root <<<'SELECT 1;'

If the command succeeds, you are affected.

MariaDB, the default implementation of the services.mysql module, is not affected. Only configurations with services.mysql.package set to pkgs.mysql84, pkgs.percona-server, or similar, are affected.

What do I need to do?

The default behavior of the module has been modified to only allow socket peer-credential authentication for the super user in the following pull-requests:

Additionally, the following pull-requests contain a regression fix when services.mysql.initialScript is used that was introduced by the security fix:

All new deployments will use this authentication method by default. However, existing deployments with a system.stateVersion lower or equal to 26.05 will not be fixed automatically to avoid, potentially, breaking production deployments. We recommend that all affected MySQL users set the root user to be authenticated by UNIX domain socket peer credentials:

[root@server:~]# mysql
mysql> ALTER USER root@localhost IDENTIFIED WITH auth_socket;
Query OK, 0 rows affected (0.04 sec)

After this, only the local root user will be able to log in as the MySQL root user.

Alternatively, if non-root local users are required to use MySQL’s root user, a password may be set instead.

Administrators wanting to disable this new default behavior and the “auto-fix” attempt can use services.mysql.secureSuperUserByDefault = false;.

Acknowledgement

We would like to thank @RafaelKr for reporting this issue and @leona for discussing the solutions and reviewing the fix.

Reference

11 Likes