web-dev-qa-db-fra.com

MySQL: Pourquoi y a-t-il des entrées "test" dans mysql.db?

Récemment, j'ai posté une réponse à une question sur mysql.db .

Ensuite, j'ai pensé que je devrais poser cette question à tout le monde:

J'ai remarqué pendant des années que lors de l'installation de MySQL 5.0+, mysql.db est rempli de deux entrées qui permettent aux utilisateurs anonymes d'accéder aux bases de données de test.

Vous pouvez le voir en exécutant cette requête:

mysql> select * from mysql.db where SUBSTR(db,1,4) = 'test'\G
*************************** 1. row ***************************
                 Host: %
                   Db: test
                 User:
          Select_priv: Y
          Insert_priv: Y
          Update_priv: Y
          Delete_priv: Y
          Create_priv: Y
            Drop_priv: Y
           Grant_priv: N
      References_priv: Y
           Index_priv: Y
           Alter_priv: Y
Create_tmp_table_priv: Y
     Lock_tables_priv: Y
     Create_view_priv: Y
       Show_view_priv: Y
  Create_routine_priv: Y
   Alter_routine_priv: N
         Execute_priv: N
*************************** 2. row ***************************
                 Host: %
                   Db: test\_%
                 User:
          Select_priv: Y
          Insert_priv: Y
          Update_priv: Y
          Delete_priv: Y
          Create_priv: Y
            Drop_priv: Y
           Grant_priv: N
      References_priv: Y
           Index_priv: Y
           Alter_priv: Y
Create_tmp_table_priv: Y
     Lock_tables_priv: Y
     Create_view_priv: Y
       Show_view_priv: Y
  Create_routine_priv: Y
   Alter_routine_priv: N
         Execute_priv: N
2 rows in set (0.00 sec)

Ces entrées sont-elles dans le mysql.db un risque pour la sécurité, et si oui, pourquoi sont-ils ajoutés par défaut à une nouvelle installation?

MISE À JOUR 2013-06-14 10:13 EDT

Ce matin, quelqu'un a voté contre ma question, que je ne comprends vraiment pas. À la lumière de cet événement, voici pourquoi j'ai pris le temps de faire une réfutation:

J'ai installé MySQL 5.6.12 pour un client cette semaine dans leur cluster de transfert. J'ai décidé de vérifier si c'était toujours un problème permanent:

mysql> select version();
+------------+
| version()  |
+------------+
| 5.6.12-log |
+------------+
1 row in set (0.00 sec)

mysql> select db,user,Host from mysql.db where LEFT(db,4)='test';
+---------+------+------+
| db      | user | Host |
+---------+------+------+
| test    |      | %    |
| test\_% |      | %    |
+---------+------+------+
2 rows in set (0.10 sec)

mysql> select now();
+---------------------+
| now()               |
+---------------------+
| 2013-06-14 10:10:13 |
+---------------------+
1 row in set (0.00 sec)

mysql>

Devinez quoi? C'est encore un problème à ce jour !!!

MORAL DE L'HISTOIRE: Veuillez vérifier votre mysql.db immédiatement après l'installation et supprimez les connexions anonymes et supprimez ces entrées de test de mysql.db sans délai.

37
RolandoMySQLDBA

Veuillez noter ce que ( Guide d'étude de certification MySQL 5.0

enter image description here

dire dans ses puces sur le Page 6 paragraphe 6:

Sous Unix, MySQL est livré avec un script d'installation mysql_secure_installation qui peut effectuer plusieurs opérations de sécurité utiles sur votre installation. Le script a les capacités suivantes:

  • Définissez un mot de passe pour les comptes root
  • Supprimez tous les comptes root accessibles à distance.
  • Supprimez les comptes d'utilisateurs anonymes. Cela améliore la sécurité car il empêche toute personne de se connecter au serveur MySQL en tant que root à partir d'un hôte distant. Le résultat est que toute personne qui souhaite se connecter en tant que root doit d'abord pouvoir se connecter sur l'hôte du serveur, ce qui fournit une barrière supplémentaire contre les attaques.
  • Supprimez la base de données de test (si vous supprimez les comptes anonymes, vous souhaiterez peut-être également supprimer la base de données de test à laquelle ils ont accès).

Pour vous débarrasser de ces mauvaises entrées, exécutez ceci s'il vous plaît:

DELETE FROM mysql.db WHERE SUBSTR(db,4) = 'test';
FLUSH PRIVILEGES;

Comme @DTest l'a mentionné dans son commentaire à la question, vous pouvez également exécuter mysql_secure_installation pour cela.

Si un utilisateur anonyme peut se connecter à MySQL à distance, une simple attaque de disque peut être lancée pour endommager l'installation de mysql. Voici un exemple:

USE test
CREATE TABLE rolando_tb (a int);
INSERT INTO rolando_tb VALUES (1);
INSERT INTO rolando_tb SELECT a FROM rolando_tb;
INSERT INTO rolando_tb SELECT a FROM rolando_tb;
INSERT INTO rolando_tb SELECT a FROM rolando_tb;
INSERT INTO rolando_tb SELECT a FROM rolando_tb;

Exécutez insert 30 fois et vous obtenez une table de 7 Go

  • Imaginez créer plusieurs de ces tables dans la base de données de test
  • Imaginez créer une procédure stockée dans la base de données de test
  • Les possibilités sont infinies tant que test et test_% existent dans mysql.db

Le sérieux de la sécurisation de l'installation de mysql n'a pas été entièrement documenté par MySQL AB, et je ne pense pas qu'Oracle ne souhaite pas le faire aujourd'hui.

MISE À JOUR 2012-02-18 16:45 EDT

Il a été suggéré par le commentaire de @ atxdba que de simplement exécuter 'DROP DATABASE test;' devrait être la méthode préférée au lieu de toucher mysql.db. La suppression de la base de données nommée test supprime simplement la base de données qui ouvre un conduit vers une faille de sécurité potentielle.

Veuillez prendre note de cette requête:

mysql> select user,Host,db from mysql.db;
+------+------+---------+
| user | Host | db      |
+------+------+---------+
|      | %    | test    |
|      | %    | test\_% |
+------+------+---------+
2 rows in set (0.09 sec)

Sur cette base, les bases de données suivantes peuvent être accessibles entièrement par des utilisateurs anonymes:

  • tester
  • test_db
  • test_001
  • test_1
  • données de test

Bien que les bases de données suivantes ne soient pas entièrement accessibles aux utilisateurs anonymes:

  • testdb
  • test1
  • données de test
  • Test (Test est différent de test dans les systèmes Linux, mais c'est toujours un problème pour MySQL fonctionnant sous Windows)

Vous devrez vous souvenir de cette règle subtile basée sur la table mysql.db. Si vous ne vous en souvenez pas, la création d'une base de données de test nommée test ou d'un nom de base de données dont les 5 premiers caractères sont test_ Rouvrira le même type de trou de sécurité.

Le moyen le plus sûr de se souvenir de ces choses est d'exécuter ces lignes après une installation initiale:

DELETE FROM mysql.db WHERE SUBSTR(db,4) = 'test' AND user='';
FLUSH PRIVILEGES;

alors n'importe quelle base de données avec n'importe quel nom peut avoir une configuration d'authentification appropriée. Vous pouvez toujours exécuter ces deux lignes à tout moment.

MISE À JOUR 2012-02-24 15:20 EDT

Pour démontrer ouvertement le danger d'avoir des utilisateurs anonymes dans mysql.db, Je voudrais créer un utilisateur qui n'a que le privilège d'utilisation.

J'utiliserai MySQL 5.5.12 sur mon bureau

Tout d'abord, regardez le mysql.db

mysql> select user,Host,db from mysql.db;
+------+------+---------+
| user | Host | db      |
+------+------+---------+
|      | %    | test    |
|      | %    | test\_% |
+------+------+---------+
2 rows in set (0.05 sec)


mysql>

Selon cela, tout Joe anonyme peut accéder à ces bases de données.

Je vais créer une base de données test_mysqldb

mysql> create database test_mysqldb;
Query OK, 1 row affected (0.00 sec)

mysql> use test_mysqldb
Database changed
mysql> show tables;
Empty set (0.00 sec)

mysql>

Créons un utilisateur ordinaire de Vanilla appelé Vanilla @ localhost (pas de mot de passe)

mysql> CREATE USER Vanilla@localhost;
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW GRANTS FOR Vanilla@localhost;
+---------------------------------------------+
| Grants for Vanilla@localhost                |
+---------------------------------------------+
| GRANT USAGE ON *.* TO 'Vanilla'@'localhost' |
+---------------------------------------------+
1 row in set (0.00 sec)

mysql>

Ensuite, à partir de la ligne de commande DOS, connectons-nous au schéma mysql

C:\>mysql -uvanilla -Dmysql
ERROR 1044 (42000): Access denied for user 'Vanilla'@'localhost' to database 'mysql'

C:\>

OK super. Voilà ce que j'attendais.

Ensuite, à partir de la ligne de commande DOS, connectons-nous au schéma test_mysqldb, créons une table et chargez-la avec des nombres

C:\>mysql -uvanilla -Dtest_mysqldb
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.5.12-log MySQL Community Server (GPL)

Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> CREATE TABLE rolando_tb (a bigint unsigned);
Query OK, 0 rows affected (0.06 sec)

mysql> INSERT INTO rolando_tb VALUES (1);
Query OK, 1 row affected (0.06 sec)

mysql> INSERT INTO rolando_tb SELECT * FROM rolando_tb;
Query OK, 1 row affected (0.06 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> INSERT INTO rolando_tb SELECT * FROM rolando_tb;
Query OK, 2 rows affected (0.08 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> INSERT INTO rolando_tb SELECT * FROM rolando_tb;
Query OK, 4 rows affected (0.06 sec)
Records: 4  Duplicates: 0  Warnings: 0

mysql> INSERT INTO rolando_tb SELECT * FROM rolando_tb;
Query OK, 8 rows affected (0.06 sec)
Records: 8  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM rolando_tb;
+------+
| a    |
+------+
|    1 |
|    1 |
|    1 |
|    1 |
|    1 |
|    1 |
|    1 |
|    1 |
|    1 |
|    1 |
|    1 |
|    1 |
|    1 |
|    1 |
|    1 |
|    1 |
+------+
16 rows in set (0.00 sec)

mysql> SELECT database();
+--------------+
| database()   |
+--------------+
| test_mysqldb |
+--------------+
1 row in set (0.00 sec)

mysql>

Avez-vous vu cela? Un utilisateur avec le privilège USAGE peut créer une table dans une base de données de test et le remplir de données. C'est un danger clair et présent . C'est pourquoi Je recommande fortement de supprimer ces entrées de test de mysql.db pour dissuader les utilisateurs anonymes d'accéder aux bases de données de test ou d'accéder aux bases de données de test nouvellement créées (via la création d'un sous-dossier sous la valeur par défaut datadir).

Pour rappel, voici comment procéder:

DELETE FROM mysql.db WHERE SUBSTR(db,4) = 'test' AND user='';
FLUSH PRIVILEGES;

MISE À JOUR 2013-09-14 20:05 EDT

Pour démontrer que la DELETE FROM mysql.db WHERE SUBSTR(db,4) = 'test' AND user=''; fonctionne réellement, j'ai exécuté ceci sur MySQL 5.6.13 aujourd'hui:

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.6.13-log MySQL Community Server (GPL)

Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> select db,user,Host from mysql.db where LEFT(db,4)='test';
+---------+------+------+
| db      | user | Host |
+---------+------+------+
| test    |      | %    |
| test\_% |      | %    |
+---------+------+------+
2 rows in set (0.43 sec)

mysql> delete from mysql.db where LEFT(db,4)='test';
Query OK, 2 rows affected (0.04 sec)

mysql> select db,user,Host from mysql.db2 where LEFT(db,4)='test';
Empty set (0.00 sec)

mysql>

Tout comme une annonce de service public, veuillez exécuter

DELETE FROM mysql.db WHERE SUBSTR(db,4) = 'test' AND user='';
FLUSH PRIVILEGES;

ou exécutez simplement mysql-secure-installation et mettez ce danger potentiel au lit.

30
RolandoMySQLDBA