MySQL: ทำไมจึงมีรายการ "ทดสอบ" ใน mysql.db


36

เมื่อเร็ว ๆ นี้ผมโพสต์คำตอบสำหรับคำถามเกี่ยวกับ 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 EDT

เช้านี้มีคนลงคะแนนคำถามของฉันซึ่งฉันไม่เข้าใจจริงๆ ในแง่ของเหตุการณ์นี้นี่คือเหตุผลที่ฉันใช้เวลาในการโต้แย้ง:

ฉันติดตั้ง MySQL 5.6.12 สำหรับลูกค้าสัปดาห์นี้ใน Staging Cluster ฉันตัดสินใจที่จะตรวจสอบเพื่อดูว่านี่ยังคงเป็นปัญหาที่เกิดขึ้น:

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โดยไม่ชักช้า


8
+1 สำหรับการนำปัญหานี้สู่ความสว่าง ฉันไม่เคยสังเกตเห็นมาก่อน แต่ฉันมักจะเรียกใช้mysql_secure_installationในการติดตั้งใหม่ซึ่งจะลบผู้ใช้ที่ไม่ระบุชื่อออก
Derek Downey

คำตอบ:


30

โปรดทราบว่าคู่มือการศึกษารับรอง MySQL 5.0คืออะไร

ป้อนคำอธิบายรูปภาพที่นี่

พูดในสัญลักษณ์ในหน้า 498 วรรค 6:

ใน Unix, MySQL มาพร้อมกับสคริปต์ mysql_secure_installation ที่สามารถทำการดำเนินการที่เกี่ยวข้องกับความปลอดภัยที่เป็นประโยชน์มากมายในการติดตั้ง สคริปต์มีความสามารถดังต่อไปนี้:

  • ตั้งรหัสผ่านสำหรับบัญชีรูท
  • ลบบัญชี root ที่สามารถเข้าถึงได้จากระยะไกล
  • ลบบัญชีผู้ใช้ที่ไม่ระบุชื่อ สิ่งนี้จะช่วยเพิ่มความปลอดภัยเนื่องจากป้องกันไม่ให้ใครก็ตามที่เชื่อมต่อกับเซิร์ฟเวอร์ MySQL เป็นรูทจากโฮสต์ระยะไกล ผลลัพธ์คือทุกคนที่ต้องการเชื่อมต่อในฐานะรูทจะต้องสามารถเข้าสู่ระบบบนโฮสต์เซิร์ฟเวอร์ได้ซึ่งจะช่วยป้องกันการโจมตีเพิ่มเติม
  • ลบฐานข้อมูลทดสอบ (หากคุณลบบัญชีที่ไม่ระบุชื่อคุณอาจต้องการลบฐานข้อมูลทดสอบที่พวกเขาสามารถเข้าถึงได้)

เพื่อกำจัดรายการที่ไม่ดีเหล่านี้ให้เรียกใช้สิ่งนี้กรุณา

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;

เรียกใช้การแทรก 30 ครั้งและคุณจะได้รับตาราง 7GB

  • ลองนึกภาพการสร้างตารางเหล่านี้หลายตารางในฐานข้อมูลทดสอบ
  • ลองนึกภาพการสร้าง Stored Procedure ในฐานข้อมูลทดสอบ
  • ความเป็นไปได้ไม่มีที่สิ้นสุดตราบใดที่การทดสอบและการทดสอบ% มีอยู่ mysql.db

ความจริงจังของการรักษาความปลอดภัยในการติดตั้ง mysql นั้นยังไม่ได้รับการจัดทำเอกสารอย่างครบถ้วนโดย MySQL AB และฉันไม่คิดว่า Oracle สนใจที่จะทำเช่นนั้นในวันนี้

อัพเดท 2012-02-18 16:45 น. EDT

มีการแนะนำโดยความคิดเห็นของ @ atxdba ว่าเพียงแค่เรียกใช้ 'การทดสอบ DATP 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 EDT

เพื่อแสดงให้เห็นถึงอันตรายของการมีผู้ใช้ที่ไม่ระบุชื่อใน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 Command Line มาเชื่อมต่อกับ schema mysql

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

C:\>

เยี่ยมมาก นั่นคือสิ่งที่ฉันคาดไว้

ถัดไปจาก DOS Command Line ลองเชื่อมต่อกับสคีมา 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 EDT

เพื่อแสดงให้เห็นว่าการ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และใส่อันตรายที่อาจเกิดขึ้นกับเตียง


ไม่ปล่อยการทดสอบฐานข้อมูล ต้องการมากกว่าอยู่ไม่สุขกับ mysqldb โดยตรง การลบรายการออกจากตาราง db จะไม่ลบไดเรกทอรี db ทดสอบจริง หากไม่มีสิ่งใดที่ดูเหมือนว่าเป็นการดูแลบ้านที่ดีกว่า
atxdba

1
ฉันต้องทำDELETE from mysql.db WHERE Db LIKE 'test%';หมายเหตุว่าการใช้อักษรตัวพิมพ์ใหญ่ของชื่อฟิลด์มีความสำคัญ ดังนั้นหากชื่อเขตข้อมูลของคุณคือDbและไม่ใช่ dbแบบสอบถามข้างต้นจะไม่ทำงาน
เอเวอรี่
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.