MySQL: Dlaczego w mysql.db są wpisy „testowe”?

37

Niedawno opublikowałem odpowiedź na pytanie dotyczące mysql.db .

Potem pomyślałem, że powinienem zadać wszystkim to pytanie:

Od lat zauważyłem, że po instalacji MySQL 5.0+ mysql.dbzapełniają go dwa wpisy, które umożliwiają dostęp do testowych baz danych przez anonimowych użytkowników.

Możesz to zobaczyć uruchamiając to zapytanie:

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)

Czy te wpisy mysql.dbstanowią zagrożenie bezpieczeństwa, a jeśli tak, to dlaczego są dodawane domyślnie do nowej instalacji?

AKTUALIZACJA 14.06.2013, 10:13 EDT

Dziś rano ktoś przegłosował moje pytanie, którego naprawdę nie rozumiem. W świetle tego wydarzenia, oto dlaczego poświęciłem czas na obalenie:

W tym tygodniu zainstalowałem MySQL 5.6.12 dla klienta w klastrze pomostowym. Postanowiłem sprawdzić, czy nadal występuje problem:

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>

Zgadnij co? To wciąż problem do dziś !!!

MORAL OF THE STORY: Sprawdź mysql.dbnatychmiast po instalacji i usuń anonimowe dane logowania i usuń mysql.dbniezwłocznie te wpisy testowe .

RolandoMySQLDBA
źródło
8
+1 za ujawnienie tego problemu. Nigdy wcześniej tego nie zauważyłem, ale zawsze uruchamiam mysql_secure_installationnową instalację, która usuwa anonimowych użytkowników.
Derek Downey

Odpowiedzi:

30

Proszę zwrócić uwagę na Przewodnik po certyfikacji MySQL 5.0

wprowadź opis zdjęcia tutaj

powiedzieć w punktach na str. 6:

W systemie Unix MySQL zawiera skrypt mysql_secure_installation, który może wykonać kilka pomocnych operacji związanych z bezpieczeństwem podczas instalacji. Skrypt ma następujące możliwości:

  • Ustaw hasło dla kont głównych
  • Usuń wszystkie zdalnie dostępne konta root.
  • Usuń anonimowe konta użytkowników. Zwiększa to bezpieczeństwo, ponieważ zapobiega możliwości łączenia się z serwerem MySQL jako root ze zdalnego hosta. W rezultacie każdy, kto chce się połączyć jako root, musi najpierw zalogować się na hoście serwera, co stanowi dodatkową barierę przed atakiem.
  • Usuń testową bazę danych (jeśli usuniesz anonimowe konta, możesz również chcieć usunąć testową bazę danych, do której mają dostęp).

Aby pozbyć się złych wpisów, uruchom to:

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

Jak wspomniano w komentarzu do pytania @DTest, możesz również uruchomić dla niego mysql_secure_installation .

Jeśli anonimowy użytkownik może zdalnie zalogować się do MySQL, można po prostu przeprowadzić atak dysku, aby zaszkodzić instalacji mysql. Oto przykład:

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;

Uruchom wkładkę 30 razy, a otrzymasz stół o pojemności 7 GB

  • Wyobraź sobie, że tworzysz kilka z tych tabel w testowej bazie danych
  • Wyobraź sobie utworzenie procedury składowanej w testowej bazie danych
  • Możliwości są nieograniczone, o ile istnieją testy i test_% mysql.db

Powaga zabezpieczenia instalacji mysql nie została w pełni udokumentowana przez MySQL AB i nie sądzę, aby Oracle była zainteresowana tym dzisiaj.

AKTUALIZACJA 2012-02-18 16:45 EDT

Sugeruje to komentarz @ atxdba, że ​​właśnie „test DROP DATABASE”; powinna być preferowaną metodą zamiast dotykania mysql.db. Usunięcie bazy danych o nazwie testpo prostu usuwa bazę danych, która otwiera kanał do potencjalnej luki bezpieczeństwa.

Proszę zwrócić uwagę na to zapytanie:

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

Na tej podstawie anonimowi użytkownicy mogą uzyskać pełny dostęp do następujących baz danych :

  • test
  • test_db
  • test_001
  • test_1
  • dane testowe

Chociaż anonimowi użytkownicy nie mogą uzyskać pełnego dostępu do następujących baz danych:

  • testdb
  • test1
  • dane testowe
  • Test ( Testróżni się od testsystemów opartych na Linuksie, ale nadal stanowi problem dla MySQL działającego w systemie Windows)

Musisz pamiętać tę subtelną zasadę opartą na mysql.dbstole. Jeśli nie pamiętasz tego, utworzenie testowej bazy danych o nazwie testlub nazwy bazy danych, której pierwszych 5 znaków test_spowoduje ponowne otwarcie tego samego typu dziury w zabezpieczeniach.

Najbezpieczniejszym sposobem na zapamiętanie tych rzeczy jest uruchomienie tych linii po pierwszej instalacji:

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

wtedy każda baza danych o dowolnej nazwie może mieć prawidłową konfigurację uwierzytelniania. Nadal możesz uruchomić te dwie linie w dowolnym momencie.

AKTUALIZACJA 2012-02-24 15:20 EDT

Aby otwarcie zademonstrować niebezpieczeństwo posiadania anonimowych użytkowników mysql.db, chciałbym utworzyć użytkownika, który ma tylko uprawnienia do używania.

Będę używać MySQL 5.5.12 na moim pulpicie

Najpierw spójrz na mysql.db

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


mysql>

Zgodnie z tym każdy anonimowy Joe może dotrzeć do tych baz danych.

Stworzę bazę danych 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>

Utwórzmy zwykłego użytkownika wanilii o nazwie vanilla @ localhost (bez hasła)

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>

Następnie, z wiersza poleceń DOS, połączmy się ze schematem mysql

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

C:\>

Ok świetnie. Tego się spodziewałem.

Następnie z wiersza poleceń systemu DOS połączmy się ze schematem test_mysqldb, utwórz tabelę i załaduj ją liczbami

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>

Widziałeś to? Użytkownik zUSAGEuprawnieniami może utworzyć tabelę w testowej bazie danych i wypełnić ją danymi. To jasne i aktualne niebezpieczeństwo . Dlatego zdecydowanie zalecam usunięcie tych wpisów testowych z mysql.db, aby zniechęcić anonimowych użytkowników do dostępu do testowych baz danych lub dostępu do nowo utworzonych testowych baz danych (poprzez utworzenie podfolderu domyślniedatadir).

Przypominamy, że tak to robisz:

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

AKTUALIZACJA 14.09.2013 20:05 EDT

Aby pokazać, że DELETE FROM mysql.db WHERE SUBSTR(db,4) = 'test' AND user='';faktycznie działa, uruchomiłem to dzisiaj na 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>

Podobnie jak ogłoszenie usługi publicznej, proszę uruchomić

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

lub po prostu uruchom bezpieczną instalację mysql i połóż to potencjalne zagrożenie.

RolandoMySQLDBA
źródło
Nie upuszcza testu bazy danych; Wolisz bezpośrednie wiercenie się mysqldb? Usunięcie wpisu z tabeli db nie spowoduje usunięcia rzeczywistego testowego katalogu db. Jeśli nic innego nie wydaje się być lepszym utrzymaniem domu
atxdba
1
Musiałem zrobić DELETE from mysql.db WHERE Db LIKE 'test%';notatkę, że wielkie litery nazwy pola mają znaczenie. Jeśli więc masz nazwę pola Dbi nie db , powyższe zapytanie nie będzie działać.
Avery,