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

37

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

Ensuite, je me suis dit que je devrais poser cette question à tout le monde:

Pendant des années, j'ai remarqué que lors de l'installation de MySQL 5.0+, mysql.dbdeux entrées permettent aux utilisateurs anonymes d'accéder à la base de données de test.

Vous pouvez le voir en lançant 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 constituent-elles mysql.dbun risque pour la sécurité et, dans l'affirmative, pourquoi sont-elles ajoutées par défaut à une nouvelle installation?

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

Ce matin, quelqu'un a voté contre ma question, ce 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 son cluster de stockage intermédiaire. J'ai décidé de vérifier si le problème persiste:

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>

Devine quoi? C'est toujours un problème même à ce jour !!!

MORAL OF THE STORY: Veuillez vérifier votre mysql.dbimmédiatement après l’installation, effacer les identifiants anonymes et effacer ces entrées de test mysql.dbsans délai.

RolandoMySQLDBA
la source
8
+1 pour avoir mis cette question à la lumière. Je ne l'avais jamais remarqué auparavant, mais je lance toujours mysql_secure_installationune nouvelle installation, qui supprime les utilisateurs anonymes.
Derek Downey

Réponses:

30

Veuillez noter quel guide d'étude de la certification MySQL 5.0

entrez la description de l'image ici

Page 498 Paragraphe 6:

Sous Unix, MySQL est fourni avec un script mysql_secure_installation qui peut effectuer plusieurs opérations utiles liées à la sécurité sur votre installation. Le script a les capacités suivantes:

  • Définir un mot de passe pour les comptes root
  • Supprimez tous les comptes root accessibles à distance.
  • Supprimer les comptes d'utilisateurs anonymes. Cela améliore la sécurité car cela évite que quiconque se connecte au serveur MySQL en tant qu'utilisateur root à partir d'un hôte distant. Il en résulte que toute personne souhaitant se connecter en tant que root doit d'abord pouvoir se connecter à l'hôte du serveur, ce qui constitue une barrière supplémentaire contre les attaques.
  • Supprimez la base de données de test (si vous supprimez les comptes anonymes, vous voudrez 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, lancez 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 pour vous.

Si un utilisateur anonyme peut se connecter à MySQL à distance, une simple attaque de disque peut être lancée pour nuire à 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 l'insertion 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 mysql n'a pas été complètement documenté par MySQL AB, et je ne pense pas que Oracle veuille l'intégrer aujourd'hui.

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

Le commentaire de @ atxdba a suggéré que le test DROP DATABASE soit exécuté; devrait être la méthode préférée par rapport à mysql.db. La testsuppression de la base de données nommée 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 sont entièrement accessibles aux utilisateurs anonymes :

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

Bien que les utilisateurs anonymes ne puissent pas accéder complètement aux bases de données suivantes:

  • testdb
  • test1
  • données de test
  • Test ( Testest différent des testsystèmes basés sur Linux, mais c'est toujours un problème pour MySQL sous Windows)

Vous devrez vous rappeler cette règle subtile basée sur la mysql.dbtable. Si vous ne vous en souvenez pas, la création d'une base de données de test nommée testou d'un nom de base de données contenant les 5 premiers caractères test_réouvrira le même type de trou de sécurité.

Le moyen le plus sûr d'éviter 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 toute 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 mysql.db, je voudrais créer un utilisateur qui ne dispose que du privilège d'utilisation.

J'utiliserai MySQL 5.5.12 sur mon bureau

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, n'importe quel 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 plain vanilla appelé vanilla @ localhost (sans 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, depuis 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. C'est ce à quoi je m'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>

As-tu vu ça? Un utilisateur disposant deUSAGEprivilèges peut créer une table dans une base de données de test et la remplir avec des 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 tests ou aux bases de données de test nouvellement créées (en créant un sous-dossier par défautdatadir).

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 cela DELETE FROM mysql.db WHERE SUBSTR(db,4) = 'test' AND user='';fonctionne réellement, j’exécutais 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>

Juste comme une annonce de service public, s'il vous plaît 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 risque potentiel au lit.

RolandoMySQLDBA
la source
N’abandonne pas le test de la base de données; préféré plutôt que de jouer avec le mysqldb? La suppression de l'entrée de la table de base de données ne supprimera pas le répertoire de base de données de test. Si rien d'autre ne semble juste comme une meilleure tenue de maison
atxdba
1
Je devais faire une DELETE from mysql.db WHERE Db LIKE 'test%';note que la capitalisation du nom de champ est importante. Donc, si votre nom de champ est Dbet non db , la requête ci-dessus ne fonctionnera pas.
Avery