MySQL: Warum gibt es "Test" -Einträge in mysql.db?

36

Kürzlich habe ich eine Antwort auf eine Frage zu mysql.db gepostet .

Dann musste ich mir überlegen, ob ich jedem diese Frage stellen sollte:

Ich habe seit Jahren festgestellt, dass bei der Installation von MySQL 5.0+ mysql.dbzwei Einträge vorhanden sind, mit denen anonyme Benutzer auf Testdatenbanken zugreifen können.

Sie können es sehen, indem Sie diese Abfrage ausführen:

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.dbHandelt es sich bei diesen Einträgen um ein Sicherheitsrisiko, und wenn ja, warum werden sie standardmäßig zu einer neuen Installation hinzugefügt?

UPDATE 2013-06-14 10:13 EDT

Heute morgen hat jemand meine Frage abgelehnt, die ich wirklich nicht verstehe. In Anbetracht dieses Ereignisses habe ich mir folgende Zeit genommen, um eine Gegenargumentation zu machen:

Ich habe diese Woche MySQL 5.6.12 für einen Client in dessen Staging-Cluster installiert. Ich habe mich entschlossen zu prüfen, ob dies immer noch ein Problem ist:

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>

Erraten Sie, was? Dies ist bis heute ein Problem !!!

MORAL DER GESCHICHTE: Bitte überprüfen Sie mysql.dbsofort nach der Installation, entfernen Sie anonyme Anmeldungen und löschen Sie diese Testeinträgemysql.db unverzüglich.

RolandoMySQLDBA
quelle
8
+1 für das Aufdecken dieses Problems. Ich habe es noch nie bemerkt, aber ich laufe immer mysql_secure_installationauf einer Neuinstallation, die die anonymen Benutzer entfernt.
Derek Downey

Antworten:

30

Bitte beachten Sie den MySQL 5.0 Certification Study Guide

Bildbeschreibung hier eingeben

sagen Sie in seinen Aufzählungspunkten auf Seite 498 Absatz 6:

Unter Unix wird MySQL mit einem mysql_secure_installation-Skript ausgeliefert, das verschiedene hilfreiche sicherheitsrelevante Vorgänge für Ihre Installation ausführen kann. Das Skript verfügt über die folgenden Funktionen:

  • Legen Sie ein Passwort für die Root-Accounts fest
  • Entfernen Sie alle remote zugänglichen Root-Konten.
  • Entfernen Sie die anonymen Benutzerkonten. Dies verbessert die Sicherheit, da verhindert wird, dass sich jemand von einem Remote-Host aus als Root mit dem MySQL-Server verbindet. Das Ergebnis ist, dass sich jeder, der eine Verbindung als Root herstellen möchte, zuerst auf dem Server-Host anmelden muss, was eine zusätzliche Barriere gegen Angriffe darstellt.
  • Entfernen Sie die Testdatenbank (Wenn Sie die anonymen Konten entfernen, möchten Sie möglicherweise auch die Testdatenbank entfernen, auf die sie Zugriff haben).

Führen Sie Folgendes aus, um diese fehlerhaften Einträge zu entfernen:

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

Wie @DTest in seinem Kommentar zu der Frage erwähnte, können Sie auch mysql_secure_installation ausführen, um dies für Sie zu tun .

Wenn sich ein anonymer Benutzer remote bei MySQL anmelden kann, kann ein einfacher Festplattenangriff gestartet werden, um die Installation von MySQL zu beeinträchtigen. Hier ist ein Beispiel:

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;

Führen Sie Insert 30-mal aus und Sie erhalten eine 7 GB-Tabelle

  • Stellen Sie sich vor, Sie erstellen mehrere dieser Tabellen in der Testdatenbank
  • Stellen Sie sich vor, Sie erstellen eine gespeicherte Prozedur in der Testdatenbank
  • Die Möglichkeiten sind endlos, solange test und test_% in existieren mysql.db

Die Ernsthaftigkeit der Sicherung der mysql-Installation wurde von MySQL AB nicht vollständig dokumentiert, und ich glaube, Oracle ist heute nicht daran interessiert.

UPDATE 18.02.2012 16:45 Uhr EDT

Es wurde von @ atxdbas Kommentar vorgeschlagen, dass nur 'DROP DATABASE test' ausgeführt wird. sollte die bevorzugte Methode gegenüber dem Berühren von mysql.db sein. Durch das Löschen der genannten Datenbank wird testlediglich die Datenbank entfernt, die einen Kanal zu einer potenziellen Sicherheitslücke öffnet.

Bitte beachten Sie diese Abfrage:

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

Auf diese Weise können anonyme Benutzer uneingeschränkt auf die folgenden Datenbanken zugreifen :

  • Prüfung
  • test_db
  • test_001
  • test_1
  • Testdaten

Auf die folgenden Datenbanken können anonyme Benutzer nicht vollständig zugreifen:

  • testdb
  • test1
  • Testdaten
  • Test ( Testunterscheidet sich von testLinux-basierten Systemen, ist aber immer noch ein Problem für MySQL unter Windows)

Sie müssen sich an diese subtile Regel erinnern, die auf der mysql.dbTabelle basiert . Wenn Sie sich nicht daran erinnern, wird durch das Erstellen einer Testdatenbank mit dem Namen testoder eines Datenbanknamens, dessen erste 5 Zeichen test_lauten, dieselbe Art von Sicherheitslücke erneut geöffnet.

Die sicherste Möglichkeit, sich an diese Dinge zu erinnern, besteht darin, diese Zeilen nach einer Erstinstallation auszuführen:

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

Dann kann jede Datenbank mit einem beliebigen Namen eine ordnungsgemäße Authentifizierung einrichten. Sie können diese beiden Zeilen jederzeit ausführen.

UPDATE 2012-02-24 15:20 EDT

Um die Gefahr, anonyme Benutzer zu haben, offen darzulegen mysql.db , , möchte ich einen Benutzer erstellen, der nur über die Nutzungsberechtigung verfügt.

Ich werde MySQL 5.5.12 auf meinem Desktop verwenden

Schauen Sie sich zuerst die Datei mysql.db an

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


mysql>

Danach kann jeder anonyme Joe diese Datenbanken erreichen.

Ich erstelle eine Datenbank 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>

Erstellen wir einen einfachen Vanille-Benutzer namens vanilla @ localhost (kein Passwort)

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>

Als nächstes stellen wir über die DOS-Befehlszeile eine Verbindung zum mysql-Schema her

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

C:\>

OK, großartig. Das habe ich erwartet.

Stellen Sie als Nächstes über die DOS-Befehlszeile eine Verbindung zum Schema test_mysqldb her, erstellen Sie eine Tabelle und laden Sie sie mit Zahlen

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>

Hast du das gesehen? Ein Benutzer mitUSAGEBerechtigungen kann eine Tabelle in einer Testdatenbank erstellen und mit Daten füllen. Dies ist eine klare und gegenwärtige Gefahr . Aus diesem Grund empfehle ich dringend, diese Testeinträge aus mysql.db zu löschen , um anonyme Benutzer davon abzuhalten, auf Testdatenbanken zuzugreifen oder auf neu erstellte Testdatenbanken zuzugreifen (indem Sie einen Unterordner unter der Standardeinstellung erstellen)datadir ).

Zur Erinnerung, so machen Sie es:

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

UPDATE 2013-09-14 20:05 EDT

Um zu demonstrieren, dass das DELETE FROM mysql.db WHERE SUBSTR(db,4) = 'test' AND user='';tatsächlich funktioniert, habe ich dies heute auf MySQL 5.6.13 ausgeführt:

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>

Nur als gemeinnützige Ankündigung, bitte ausführen

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

oder einfach mysql-secure-installation ausführen und diese potenzielle gefahr ins bett legen.

RolandoMySQLDBA
quelle
Ist kein Datenbanktest; lieber direkt mit dem mysqldb zappeln? Durch das Löschen des Eintrags aus der DB-Tabelle wird das tatsächliche Test-DB-Verzeichnis nicht entfernt. Wenn nichts anderes so aussieht wie besseres
Housekeeping
1
Ich musste einen DELETE from mysql.db WHERE Db LIKE 'test%';Hinweis machen, dass die Großschreibung des Feldnamens wichtig ist. Wenn Ihr Feldname also ist Dbund nicht db , funktioniert die obige Abfrage nicht.
Avery