MySQL: Mengapa ada entri "test" di mysql.db?

37

Baru-baru ini, saya memposting jawaban untuk pertanyaan tentang mysql.db .

Kemudian, saya berpikir saya harus bertanya kepada semua orang pertanyaan ini:

Saya telah memperhatikan selama bertahun-tahun bahwa pada saat instalasi MySQL 5.0+, mysql.dbdiisi dengan dua entri yang memungkinkan database uji untuk diakses oleh pengguna anonim.

Anda dapat melihatnya dengan menjalankan kueri ini:

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)

Apakah entri ini dalam mysql.dbrisiko keamanan, dan jika demikian, mengapa mereka ditambahkan secara default ke instalasi baru?

UPDATE 2013-06-14 10:13 EDT

Pagi ini seseorang menjatuhkan pertanyaan saya, yang saya benar-benar tidak mengerti. Mengingat peristiwa ini, inilah mengapa saya meluangkan waktu untuk membuat bantahan:

Saya menginstal MySQL 5.6.12 untuk klien minggu ini di Staging Cluster mereka. Saya memutuskan untuk memeriksa apakah ini masih merupakan masalah yang sedang berlangsung:

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>

Tebak apa? Ini masih menjadi masalah bahkan hingga hari ini !!!

MORAL OF THE STORY: Silakan periksa Anda mysql.dbsegera setelah instalasi dan hapus login anonim dan hapus entri tes ini dari mysql.dbtanpa penundaan.

RolandoMySQLDBA
sumber
8
+1 untuk mengangkat masalah ini. Saya tidak pernah menyadarinya sebelumnya, tetapi saya selalu menjalankan mysql_secure_installationinstalasi baru, yang menghapus pengguna anonim.
Derek Downey

Jawaban:

30

Harap dicatat apa Panduan Studi Sertifikasi MySQL 5.0

masukkan deskripsi gambar di sini

katakan dalam bulletpoints pada Halaman 498 Paragraf 6:

Di Unix, MySQL dilengkapi dengan skrip mysql_secure_installation yang dapat melakukan beberapa operasi terkait keamanan yang bermanfaat pada instalasi Anda. Script memiliki kemampuan sebagai berikut:

  • Tetapkan kata sandi untuk akun root
  • Hapus semua akun root yang dapat diakses dari jarak jauh.
  • Hapus akun pengguna anonim. Ini meningkatkan keamanan karena mencegah kemungkinan siapa pun terhubung ke server MySQL sebagai root dari host jarak jauh. Hasilnya adalah siapa pun yang ingin terhubung sebagai root harus terlebih dahulu dapat masuk pada host server, yang memberikan penghalang tambahan terhadap serangan.
  • Hapus database pengujian (Jika Anda menghapus akun anonim, Anda mungkin juga ingin menghapus database pengujian yang mereka akses).

Untuk menghilangkan entri yang buruk itu, jalankan ini:

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

Seperti @DTest disebutkan dalam komentarnya untuk pertanyaan, Anda juga dapat menjalankan mysql_secure_installation untuk ini untuk Anda.

Jika pengguna anonim dapat login ke MySQL dari jarak jauh, serangan disk dapat diluncurkan untuk merusak instalasi mysql. Berikut ini sebuah contoh:

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;

Jalankan masukkan 30 kali dan Anda mendapatkan tabel 7GB

  • Bayangkan membuat beberapa tabel ini di database pengujian
  • Bayangkan membuat Prosedur Disimpan dalam database uji
  • Kemungkinan tidak terbatas selama test dan test_% ada di mysql.db

Seriusnya pengamanan instalasi mysql belum sepenuhnya didokumentasikan oleh MySQL AB, dan saya pikir Oracle tidak tertarik untuk melakukannya hari ini.

UPDATE 2012-02-18 16:45 EDT

Disarankan oleh komentar @ atxdba bahwa hanya menjalankan 'DROP DATABASE test;' harus menjadi metode yang disukai daripada menyentuh mysql.db. Menjatuhkan nama database testhanya menghapus database yang membuka saluran ke lubang keamanan potensial.

Harap perhatikan permintaan ini:

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

Berdasarkan ini, basis data berikut dapat diakses sepenuhnya oleh pengguna anonim :

  • uji
  • test_db
  • test_001
  • test_1
  • test_data

Meskipun basis data berikut tidak dapat diakses sepenuhnya oleh pengguna anonim:

  • testdb
  • test1
  • testdata
  • Test ( Testberbeda dari testsistem berbasis Linux, tetapi masih masalah untuk MySQL yang berjalan di Windows)

Anda harus mengingat aturan halus ini berdasarkan pada mysql.dbtabel. Jika Anda tidak ingat ini, membuat database uji bernama testatau nama database yang 5 karakter pertamanya test_akan membuka kembali jenis lubang keamanan yang sama.

Cara paling aman untuk mengingat hal-hal ini adalah dengan menjalankan baris-baris ini setelah instalasi awal:

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

maka basis data apa pun dengan nama apa pun dapat memiliki pengaturan otentikasi yang tepat. Anda masih dapat menjalankan dua baris ini kapan saja.

UPDATE 2012-02-24 15:20 EDT

Untuk secara terbuka menunjukkan bahaya memiliki pengguna anonim mysql.db, saya ingin membuat pengguna yang hanya memiliki hak penggunaan.

Saya akan menggunakan MySQL 5.5.12 di Desktop saya

Pertama, lihat mysql.db

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


mysql>

Menurut ini, setiap anonim Joe dapat mencapai database ini.

Saya akan membuat database 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>

Mari kita buat pengguna vanilla polos bernama vanilla @ localhost (tanpa kata sandi)

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>

Selanjutnya, dari DOS Command Line, mari kita sambungkan ke skema mysql

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

C:\>

OK bagus. Itu yang saya harapkan.

Selanjutnya, dari Baris Perintah DOS, mari kita sambungkan ke skema test_mysqldb, buat tabel, dan muat dengan angka

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>

Apakah kamu melihat itu? Seorang pengguna denganUSAGEhak istimewa dapat membuat tabel dalam database uji dan mengisinya dengan data. Ini bahaya yang jelas dan sekarang . Inilah sebabnya saya sangat menyarankan untuk menghapus entri tes tersebut dari mysql.db untuk mencegah pengguna anonim dari mencapai basis data pengujian atau mengakses basis data pengujian yang baru dibuat (melalui membuat subfolder di bawah defaultdatadir).

Sebagai pengingat, ini adalah bagaimana Anda melakukannya:

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

UPDATE 2013-09-14 20:05 EDT

Untuk menunjukkan bahwa DELETE FROM mysql.db WHERE SUBSTR(db,4) = 'test' AND user='';sebenarnya berfungsi, saya menjalankan ini di MySQL 5.6.13 hari ini:

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>

Sama seperti pengumuman layanan publik, silakan jalankan

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

atau jalankan mysql-secure-installation dan letakkan potensi bahaya ini di tempat tidur.

RolandoMySQLDBA
sumber
Tidak membatalkan tes basis data; lebih disukai daripada langsung gelisah dengan mysqldb? Menghapus entri dari tabel db tidak akan menghapus direktori test db yang sebenarnya. Jika tidak ada hal lain yang sepertinya seperti
perawatan
1
Saya harus melakukan DELETE from mysql.db WHERE Db LIKE 'test%';Note bahwa kapitalisasi nama bidang itu penting. Jadi, jika nama bidang Anda adalah Dbdan tidak db , kueri di atas tidak akan berfungsi.
Avery