MySQL: почему в mysql.db есть «тестовые» записи?

37

Недавно я опубликовал ответ на вопрос о mysql.db .

Затем я подумал, что должен задать всем этот вопрос:

В течение многих лет я замечал, что после установки MySQL 5.0+ mysql.dbзаполняются две записи, которые позволяют анонимным пользователям получать доступ к тестовым базам данных.

Вы можете увидеть это, запустив этот запрос:

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)

Являются ли эти записи mysql.dbугрозой безопасности, и если да, то почему они по умолчанию добавляются в новую установку?

ОБНОВЛЕНИЕ 2013-06-14 10:13 ПО ВОСТОЧНОМУ ВРЕМЕНИ

Этим утром кто-то отклонил мой вопрос, который я действительно не понимаю. В свете этого события вот почему я нашел время, чтобы сделать опровержение:

Я установил MySQL 5.6.12 для клиента на этой неделе в его промежуточном кластере. Я решил проверить, было ли это все еще продолжающейся проблемой:

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>

Угадай, что? Это все еще проблема даже по сей день !!!

МОРАЛЬ ИСТОРИИ: Пожалуйста, проверьте ваш mysql.dbсразу после установки и удалите анонимные логины и удалите эти тестовые записи mysql.dbбез задержки.

RolandoMySQLDBA
источник
8
+1 за освещение этой проблемы. Я никогда не замечал этого раньше, но я всегда запускаю mysql_secure_installationновую установку, которая удаляет анонимных пользователей.
Дерек Дауни

Ответы:

30

Обратите внимание, что руководство по сертификации MySQL 5.0

введите описание изображения здесь

в пунктах 6 на стр. 498 сказать:

В Unix MySQL поставляется со скриптом mysql_secure_installation, который может выполнять несколько полезных операций, связанных с безопасностью вашей установки. Скрипт имеет следующие возможности:

  • Установите пароль для корневых учетных записей
  • Удалите все удаленно доступные корневые учетные записи.
  • Удалите учетные записи анонимных пользователей. Это повышает безопасность, поскольку предотвращает возможность любого подключения к серверу MySQL в качестве пользователя root с удаленного хоста. В результате любой, кто хочет подключиться как root, должен сначала войти в систему на хосте сервера, что создает дополнительный барьер против атаки.
  • Удалите тестовую базу данных (при удалении анонимных учетных записей вы также можете удалить тестовую базу данных, к которой они имеют доступ).

Чтобы избавиться от этих плохих записей, запустите это:

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

Как отметил @DTest в своем комментарии к вопросу, вы также можете запустить mysql_secure_installation для этого.

Если анонимный пользователь может войти в MySQL удаленно, можно запустить простую атаку диска, чтобы повредить установку mysql. Вот пример:

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;

Запустите insert 30 раз, и вы получите таблицу 7 ГБ

  • Представьте себе создание нескольких из этих таблиц в тестовой базе данных
  • Представьте себе создание хранимой процедуры в тестовой базе данных
  • Возможности бесконечны, пока существуют test и test_% в mysql.db

Серьезность обеспечения установки MySQL не была полностью задокументирована MySQL AB, и я не думаю, что Oracle заинтересована в этом сегодня.

ОБНОВЛЕНИЕ 2012-02-18 16:45 ПО ВОСТОЧНОМУ ВРЕМЕНИ

В комментарии @ atxdba было сказано, что просто запускается тест DROP DATABASE; должен быть предпочтительным методом по сравнению с прикосновением mysql.db. Удаление указанной базы данных testпросто удаляет базу данных, которая открывает канал к потенциальной дыре в безопасности.

Пожалуйста, обратите внимание на этот запрос:

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

Исходя из этого, следующие базы данных могут быть полностью доступны анонимным пользователям :

  • тест
  • test_db
  • test_001
  • test_1
  • test_data

Хотя следующие базы данных не могут быть полностью доступны анонимным пользователям:

  • TESTDB
  • test1
  • TestData
  • Тест ( Testотличается от testсистем на базе Linux, но все еще остается проблемой для MySQL, работающего в Windows)

Вам нужно будет запомнить это тонкое правило, основанное на mysql.dbтаблице. Если вы этого не помните, при создании тестовой базы данных с именем testили именем базы данных, первые 5 символов которого test_будут открыты, дыра в безопасности того же типа.

Самый безопасный способ запомнить эти вещи - запустить эти строки после первоначальной установки:

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

тогда любая база данных с любым именем может иметь правильную настройку аутентификации. Вы все еще можете запустить эти две строки в любое время.

ОБНОВЛЕНИЕ 2012-02-24 15:20 ПО ВОСТОЧНОМУ ВРЕМЕНИ

Чтобы открыто продемонстрировать опасность наличия анонимных пользователей в mysql.db , я хотел бы создать пользователя, который имеет только привилегию использования.

Я буду использовать MySQL 5.5.12 на своем рабочем столе

Во-первых, посмотрите на mysql.db

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


mysql>

Согласно этому, любой анонимный Джо может получить доступ к этим базам данных.

Я создам базу данных 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>

Давайте создадим простого пользователя vanilla с именем vanilla @ localhost (без пароля)

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>

Далее, из командной строки DOS, давайте подключимся к схеме mysql

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

C:\>

Ок, отлично. Это то, что я ожидал.

Далее, из командной строки DOS, давайте соединимся со схемой test_mysqldb, создадим таблицу и загрузим ее с числами

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>

Ты это видел? Пользователь сUSAGEпривилегией может создать таблицу в тестовой базе данных и заполнить ее данными. Это явная и настоящая опасность . Вот почему я настоятельно рекомендую удалить эти тестовые записи из mysql.db, чтобы анонимные пользователи не могли получить доступ к тестовым базам данных или получить доступ к вновь созданным тестовым базам данных (путем создания подпапки по умолчаниюdatadir ).

Как напоминание, вот как вы это делаете:

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

ОБНОВЛЕНИЕ 2013-09-14 20:05 ПО ВОСТОЧНОМУ ВРЕМЕНИ

Чтобы продемонстрировать, что это DELETE FROM mysql.db WHERE SUBSTR(db,4) = 'test' AND user='';действительно работает, я запустил это на MySQL 5.6.13 сегодня:

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>

Пожалуйста, запустите

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

или просто запустите mysql-secure-installation и положите эту потенциальную опасность в постель.

RolandoMySQLDBA
источник
Не отбрасывать тест базы данных; предпочтительнее прямой ерзанки с mysqldb? Удаление записи из таблицы БД не приведет к удалению фактического каталога тестовой БД. Если ничто иное, это не кажется лучшим
ведением
1
Я должен был сделать DELETE from mysql.db WHERE Db LIKE 'test%';примечание, что заглавная буква названия поля имеет значение. Так что если ваше имя поля Dbи нет db , запрос выше не будет работать.
Эвери