it-swarm.it

MySQL: Perché ci sono voci "test" in mysql.db?

Di recente, ho pubblicato una risposta a una domanda su mysql.db .

Quindi, ho pensato che avrei dovuto porre a tutti questa domanda:

Ho notato per anni che all'installazione di MySQL 5.0+, mysql.db è popolato con due voci che consentono agli utenti anonimi di accedere ai database di prova.

Puoi vederlo eseguendo questa query:

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)

Sono queste voci in mysql.db un rischio per la sicurezza e, in tal caso, perché vengono aggiunti per impostazione predefinita a una nuova installazione?

AGGIORNAMENTO 2013-06-14 10:13 EDT

Questa mattina qualcuno ha annullato la mia domanda, che davvero non capisco. Alla luce di questo evento, ecco perché mi sono preso il tempo per fare una confutazione:

Questa settimana ho installato MySQL 5.6.12 per un client nel loro cluster di gestione temporanea. Ho deciso di verificare se questo fosse ancora un problema in corso:

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>

Indovina un po '? Questo è ancora un problema fino ad oggi !!!

MORALE DELLA STORIA: Controlla il tuo mysql.db subito dopo l'installazione, rimuovi accessi anonimi e cancella queste voci di test da mysql.db senza indugio.

37
RolandoMySQLDBA

Nota cosa Guida allo studio della certificazione MySQL 5.0

enter image description here

dire nei suoi punti alla pagina 498 paragrafo 6:

Su Unix, MySQL viene fornito con uno script mysql_secure_installation che può eseguire diverse utili operazioni di sicurezza sulla tua installazione. Lo script ha le seguenti funzionalità:

  • Imposta una password per gli account di root
  • Rimuovere eventuali account root accessibili in remoto.
  • Rimuovi gli account utente anonimo. Questo migliora la sicurezza perché impedisce a chiunque di connettersi al server MySQL come root da un host remoto. Il risultato è che chiunque desideri connettersi come root deve prima essere in grado di accedere all'host del server, il che fornisce una barriera aggiuntiva contro gli attacchi.
  • Rimuovere il database di prova (se si rimuovono gli account anonimi, è possibile che si desideri rimuovere anche il database di prova a cui hanno accesso).

Per sbarazzarsi di quelle voci sbagliate, eseguire questo per favore:

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

Come @DTest ha menzionato nel suo commento alla domanda, puoi anche eseguire mysql_secure_installation per questo per te.

Se un utente anonimo può accedere a MySQL da remoto, può essere lanciato un attacco al disco per danneggiare l'installazione di mysql. Ecco un esempio:

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;

Esegui insert 30 volte e otterrai un tavolo da 7 GB

  • Immagina di creare molte di queste tabelle nel database di test
  • Immagina di creare una Stored Procedure nel database di test
  • Le possibilità sono infinite fintanto che test e test_% esistono in mysql.db

La serietà di proteggere l'installazione di mysql non è stata completamente documentata da MySQL AB e non credo che Oracle sia interessata a farlo oggi.

AGGIORNAMENTO 2012-02-18 16:45 EDT

Il commento di @ atxdba mi ha suggerito di eseguire semplicemente "DROP DATABASE test;" dovrebbe essere il metodo preferito rispetto a toccare mysql.db. Il rilascio del database denominato test rimuove semplicemente il database che apre un condotto verso una potenziale falla di sicurezza.

Si prega di prendere nota di questa domanda:

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

Sulla base di questo, i seguenti database possono essere accessibile completamente da utenti anonimi:

  • test
  • tEST_DB
  • test_001
  • tEST_1
  • dati di test

Mentre gli utenti anonimi non possono accedere completamente ai seguenti database:

  • testdb
  • test1
  • dati di test
  • Test (Test è diverso da test nei sistemi basati su Linux, ma è ancora un problema per MySQL in esecuzione su Windows)

Dovrai ricordare questa regola sottile basata sulla tabella mysql.db. Se non lo ricordi, la creazione di un database di test denominato test o un nome di database i cui primi 5 caratteri è test_ Riapriranno lo stesso tipo di falla di sicurezza.

Il modo più sicuro per evitare di ricordare queste cose è eseguire queste linee dopo un'installazione iniziale:

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

quindi qualsiasi database con qualsiasi nome può avere una corretta configurazione di autenticazione. Puoi comunque eseguire queste due righe in qualsiasi momento.

AGGIORNAMENTO 2012-02-24 15:20 EDT

Per dimostrare apertamente il pericolo di avere utenti anonimi in mysql.db, Vorrei creare un utente che ha solo il privilegio di utilizzo.

Userò MySQL 5.5.12 sul mio desktop

Innanzitutto, guarda mysql.db

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


mysql>

In base a ciò, qualsiasi Joe anonimo può raggiungere questi database.

Creerò un 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>

Creiamo un semplice utente Vanilla chiamato Vanilla @ localhost (nessuna password)

mysql> CREATE USER [email protected];
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW GRANTS FOR [email protected];
+---------------------------------------------+
| Grants for [email protected]                |
+---------------------------------------------+
| GRANT USAGE ON *.* TO 'Vanilla'@'localhost' |
+---------------------------------------------+
1 row in set (0.00 sec)

mysql>

Quindi, dalla riga di comando DOS, connettiamoci allo schema mysql

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

C:\>

Ok fantastico. Questo è quello che mi aspettavo.

Quindi, dalla riga di comando DOS, connettiamoci allo schema test_mysqldb, creiamo una tabella e carichiamola con i numeri

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>

L'hai visto? Un utente con privilegio USAGE può creare una tabella in un database di test e riempilo di dati. Questo è un pericolo chiaro e presente . Questo è il motivo per cui Consiglio vivamente di eliminare quelle voci di test da mysql.db per dissuadere gli utenti anonimi dal raggiungere database di test o accedere a database di test appena creati (creando una sottocartella con il valore predefinito datadir).

Come promemoria, ecco come lo fai:

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

AGGIORNAMENTO 2013-09-14 20:05 EDT

Per dimostrare che DELETE FROM mysql.db WHERE SUBSTR(db,4) = 'test' AND user=''; funziona davvero, oggi ho eseguito questo su 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>

Proprio come un annuncio di servizio pubblico, si prega di eseguire

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

o semplicemente esegui mysql-secure-installation e metti a rischio questo potenziale pericolo.

30
RolandoMySQLDBA