ugrás a tartalomhoz

A MySQL biztonsági kérdései

Baranyai László · 2004. Május. 15. (Szo), 21.00
A MySQL biztonsági kérdései
Az SQL adatbázisok használatba vétele során a legelső lépés az adattáblák szerkezetének (mezők és relációk) megtervezése úgy, hogy az illeszkedjen a várható lekérdezésekhez. Sajnos az adatbázisok tényleges létrehozása során sokan kihagyják a jogosultságok megfelelő beállítását és ellenőrzését. A kisebbik rossz, ha kevesebb jogot kaptunk, mert azt azonnal észrevesszük, amint dolgozni szeretnénk. Komolyabb problémát okozhat, ha több jogot kaptunk, mert egy elgépelt utasítás belerondíthat mások adatbázisába is ahelyett, hogy hibaüzenetet kapnánk.

Adatbázis létrehozása

A táblák, adamezők létrehozását és kezelését szolgáló parancsokat a test nevű adatbázison gyakorolhatjuk. Ez telepítés után egy üres adatbázis, amihez minden felhasználónak minden joga megvan. Amennyiben megkaptuk a jogot, hogy belépjünk a szerverre (ssh-val), használhatjuk a mysql parancsot. Mielőtt bármit is teszünk, győződjünk meg róla, hogy senki más adatait nem töröljük, módosítjuk!

$ mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 23 to server version: 3.23.49-log

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> use test;
Database changed

mysql> show tables;
Empty set (0.00 sec)
A test nevű adatbázis üres, tehát bátran elkezdhetjük a munkát. Ha a sor végén nincsen ';' jel, az ENTER leütése után új sorban folytathatjuk a parancs begépelését és kicsit áttekinthetőbb lesz amit írunk. Nagy segítség, ha közben olvasni tudjuk a MySQL leírását is a www.mysql.com oldalon, vagy onnan letölti a kézikönyvet PDF formátumban.

mysql> create table valami (
    -> kod int,
    -> neve varchar(200),
    -> megjegyzes text );
Query OK, 0 rows affected (0.00 sec)

mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| valami         |
+----------------+
1 row in set (0.00 sec)

mysql> desc valami;
+------------+--------------+------+-----+---------+-------+
| Field      | Type         | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+-------+
| kod        | int(11)      | YES  |     | NULL    |       |
| neve       | varchar(200) | YES  |     | NULL    |       |
| megjegyzes | text         | YES  |     | NULL    |       |
+------------+--------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
Ha befejeztük a gyakorlást a test adatbázisban, a rendrakás kötelező! A létrehozott tábla törlését a drop parancs segítségével tehetjük meg.

mysql> drop table valami;
Query OK, 0 rows affected (0.00 sec)

mysql> show tables;
Empty set (0.00 sec)
Elegánsabb megoldás, ha előre eltervezünk mindent és a megfelelő parancsokat egy szöveges állományba gyűjtjük. Sok esetben ez elkerülhetetlen, mert a szolgáltató nem ad nekünk jogot adatbázisok és táblák létrehozásához. Ilyenkor az elkészített parancsállományt kell eljuttatni a rendszergazdához. Ha mi hozzuk létre az adatbázist, akkor az első sorba create database sajat_db kerül (értelemszerűen sajat_db tetszőleges név lehet). Az utasítások kerüljenek most valami.sql-be:

use test;

create table valami (
 kod int,
 neve varchar(200),
 megjegyzes text
);
Használata pedig nagyon egyszerű, DOS (Windows) és Linux alatt is működik a következő példa:

$ mysql <valami.sql

Adminisztráció grafikus felületen

Természetesen léteznek grafikus kezelői felületek is, amelyek megkönnyítik a munkát. Kettőt tudok ajánlani:
  • phpMyAdmin
    Az adatbázis kezeléséhez PHP osztályokat használ, telepítése után a webszerveren keresztül kommunikálhatunk vele (tetszőleges böngésző programban behívható).
  • MySQL Control Center
    A Trolltech Qt nevű elemtárára épülő alkalmazás elérhető Linux és Windows operációs rendszerekhez (letölthető a forráskódja is).

Ellenőrzés PHP programmal

Érdemes egy kisebb PHP programot írni, amely feltérképezi, hogy mely adatbázisok milyen tábláihoz férhetünk hozzá egy adott felhasználói névvel és jelszóval. Az alábbi függvény kapcsolatot teremt a MySQL szerverrel, majd a mysql_list_dbs segítségével lekérdezi az összes adatbázis nevét, majd a mysql_list_tables segítségével megpróbálja kilistázni a benne levő táblákat. A hozzáférhető táblák összes mező elemét névvel, típussal és mérettel kiírja.

<?php

function MySQL_Test($server_name,$user_name,$password)
{

 if (!($DBLink=mysql_connect($server_name,$user_name,$password))) {
  echo "Error: Cannot connect to database!";
  exit;
 }
 echo "<code>\n";
 echo "Accepted connection. ID = " . $DBLink . "\n";
 if ($DBRes = mysql_list_dbs($DBLink)) {
  while ($db_row = mysql_fetch_row($DBRes)) {
   echo "&amp;lt;Database '<b>" . $db_row[0] . "</b>'&amp;gt;\n";
   if ($TBRes = mysql_list_tables($db_row[0],$DBLink)) {
    while ($tb_row = mysql_fetch_row($TBRes)) {
     echo "  &amp;lt;Table '<i>$tb_row[0]</i>'&amp;gt;\n";
     if ($FDRes = mysql_list_fields($db_row[0],$tb_row[0],$DBLink)) {
      for ($i=0;$i<mysql_num_fields($FDRes);$i++) {
       echo "   ";
       echo mysql_field_name($FDRes, $i) . " ";
       echo mysql_field_type($FDRes, $i) . "(";
       echo mysql_field_len($FDRes, $i) . ")";
       echo " " . mysql_field_flags($FDRes, $i) . "\n";
      }
     }
     echo "  &amp;lt;/Table&amp;gt;\n";
    }
   }
   echo "&amp;lt;/Database&amp;gt;\n";
  }
 }
 echo "</code>\n";
 mysql_close($DBLink);

}

?>
A függvény alkalmazására másik PHP programot javaslok, amely akár egy form adatait is használhatja. Most a legegyszerűbb esetet mutatnám be:

<?php

 include "mysql_test.php";
 MySQL_Test("localhost","root","");

?>
Ha a fenti listázás eredményes, sürgősen nézzünk utána a jogok beállításának a MySQL kézikönyv vonatkozó részeiben. A "root" névvel és jelszó nélkül üzemeltetett adatbázisokhoz bárki hozzáférhet korlátozások nélkül (nem kell sok fantázia hozzá, hogy egy cracker ezt a párosítást kipróbálja).

Megfelelő jogosultság esetén a böngésző ablakában látható lista csak test adatbázis részleteit ismerteti.

Accepted connection. ID = Resource id #1

<Database 'mysql'>
</Database>
<Database 'test'>
 <Table 'valami'>
  kod int(11)
  neve string(200)
  megjegyzes blob(65535) blob
 </Table>
</Database>
Rosszul beállított jogok esetén (pl. "root" felhasználó jelszó nélkül) mindenhez korlátlan hozzáférésünk van, így láthatóvá válik a mysql adatbázis is. Ebben tárolja a MySQL szerver az adatbázisok és felhasználóik jogait, korlátozásait.

<Database 'mysql'>
 <Table 'columns_priv'>
  Host string(60) not_null primary_key binary
  Db string(64) not_null primary_key binary
  User string(16) not_null primary_key binary
  Table_name string(64) not_null primary_key binary
  Column_name string(64) not_null primary_key binary
  Timestamp timestamp(14) not_null unsigned zerofill timestamp
  Column_priv string(31) not_null set
 </Table>
 <Table 'db'>
  Host string(60) not_null primary_key binary
  Db string(64) not_null primary_key binary
  User string(16) not_null primary_key multiple_key binary
  Select_priv string(1) not_null enum
  Insert_priv string(1) not_null enum
  Update_priv string(1) not_null enum
  Delete_priv string(1) not_null enum
  Create_priv string(1) not_null enum
  Drop_priv string(1) not_null enum
  Grant_priv string(1) not_null enum
  References_priv string(1) not_null enum
  Index_priv string(1) not_null enum
  Alter_priv string(1) not_null enum
 </Table>
 <Table 'func'>
  name string(64) not_null primary_key binary
  ret int(1) not_null
  dl string(128) not_null
  type string(9) not_null enum
 </Table>
 <Table 'host'>
  Host string(60) not_null primary_key binary
  Db string(64) not_null primary_key binary
  Select_priv string(1) not_null enum
  Insert_priv string(1) not_null enum
  Update_priv string(1) not_null enum
  Delete_priv string(1) not_null enum
  Create_priv string(1) not_null enum
  Drop_priv string(1) not_null enum
  Grant_priv string(1) not_null enum
  References_priv string(1) not_null enum
  Index_priv string(1) not_null enum
  Alter_priv string(1) not_null enum
 </Table>
 <Table 'tables_priv'>
  Host string(60) not_null primary_key binary
  Db string(64) not_null primary_key binary
  User string(16) not_null primary_key binary
  Table_name string(60) not_null primary_key binary
  Grantor string(77) not_null multiple_key
  Timestamp timestamp(14) not_null unsigned zerofill timestamp
  Table_priv string(68) not_null set
  Column_priv string(31) not_null set
 </Table>
 <Table 'user'>
  Host string(60) not_null primary_key binary
  User string(16) not_null primary_key binary
  Password string(16) not_null binary
  Select_priv string(1) not_null enum
  Insert_priv string(1) not_null enum
  Update_priv string(1) not_null enum
  Delete_priv string(1) not_null enum
  Create_priv string(1) not_null enum
  Drop_priv string(1) not_null enum
  Reload_priv string(1) not_null enum
  Shutdown_priv string(1) not_null enum
  Process_priv string(1) not_null enum
  File_priv string(1) not_null enum
  Grant_priv string(1) not_null enum
  References_priv string(1) not_null enum
  Index_priv string(1) not_null enum
  Alter_priv string(1) not_null enum
 </Table>
</Database>

Összefoglalás

A programozók a hagyományos szemlélet alapján (és az adatbázis szerver felhasználóinak ellenőrzése érdekében) általában előnyben részesítik a kész SQL szkriptek almalkazását az adatbázisok létrehozása során, hiszen ez a munka komolyabb átgondolását kényszeríti ki. A grafikus kezelői felületek sok kényelmi funkcióval rendelkeznek, nagyobb méretű fejlesztéseknél nagyságrendekkel gyorsíthatják a munkát.

Bárhogy hozzuk is létre az adatbázisainkat és azok tábláit, utólag érdemes ellenőrizni a beállításokat. Ilyenkor nem elegendő végigfutni a kezelő felület menürendszerén, mert sok esetben nem is vesszük észre a saját hibánkat, vagy a kapott listákból az nem is látható. Mindig más módszert válasszunk az ellenőrzésre és az adminisztrációra! Ez a redundancia nagyobb biztonságot nyújt.

A helytelen beállítások veszélye nem csupán abban rejlik, hogy bárki elolvashatja a rögzített adatokat, de korlátlanul módosíthat és törölhet is az illetéktelen felhasználó (pl.: "root" jelszó nélkül). Ha szervert üzemeltet, a "root" nevű felhasználó jelszavát mindenképp állítsa be (ez a leggyakoribb hiba, amivel én találkoztam)!
 
Baranyai László arcképe
Baranyai László
A Budapesti Corvinus Egyetem docense, munkája egyben a hobbija is (szeret oktatni és programozni). Több tudományos honlap tervezője, készítője. Szeret nassolni és saját bevallása szerint jó palacsintát süt.
1

Jogosultságok

Anonymous · 2004. Jún. 3. (Cs), 18.06
A select,insert,update,delete jogok általában (mindig) kellenek, többre azonban eddig (3 év alatt) nem volt szükség. Nem tudom, nekem úgy tűnik, ha egy adatbázis ezekkel a jogokkal bír, akkor az a MySQL oldaláról elégséges is a munkához, és másokra nézve sem jelent veszélyt. (A PHP-oldali hanyagság, a formokban kapott értékek ellenőrzés nélküli feldolgozása más kérdés, azt hiszem.)
Én a grafikus front-endeket szeretem (Win alatt fejlesztek), és a kedvencem a MySQlFront2.5. Múltkor komoly bajba is kerültem emiatt, mert fejből már egy vacak táblát sem tudok azonnal létrehozni, szégyenszemre a manualt kellett használnom. :) Más kérdés, hogy bizonyos lekérdezéseket meg épp a programból tanultam meg kezdetben, mert okosan kiírja az épp végrehajtott, kattintgatással előidézett kérés SQL-nyelvű megfelelőjét.
2

manual

kmm · 2004. Jún. 4. (P), 06.45
manual hasznalata nem szegyen!

--
üdv: kmm...
3

Jogok

Anonymous · 2004. Jún. 7. (H), 14.08
Azért szerintem egy ALTER nem rossz dolog, hátha kell valamit módosítani a tábla szerkezeten.. A többi mondjuk tényleg nem feltétlenül kell.
4

alter mint adatbazishasznalat

kmm · 2004. Jún. 8. (K), 16.00
nehezen tudok elkepzelni olyan adatbazis alkalmazast, ami jol van megirva aes alterelgetni kell a tablakat... adatbazis igazabol szerintem egy fix szerkezetet takar, ami igazodik az adatok milyensegehez is, azaz ha az adatok flexibilisek, akkor az adatbazis struktura is az

--
üdv: kmm...
6

ALTER

tgergely · 2011. Júl. 13. (Sze), 08.46
Találkoztam olyan alkalmazással, ahol az egyedi felhasználói mezők kezelése úgy volt megoldva, hogy amit összekattingattál az admin felületen azt a rendszer ALTER TABLE ADD COLUMN-al hozzáadogatta a táblához. Szerintem ez nem feltétlen rossz, lenézendő megoldás.
7

7 éves topic

solkprog · 2011. Júl. 13. (Sze), 12.02
(7 éves hozászolásra válaszoltál.)

De szerintem nincs igazad, egy alkalmazás ne (nagyon) adogasson oszlopokat a táblához. Ráadásul az oszlopok száma sok DBMS-ben (erősen) korlátozott.
5

re: Jogok

Anonymous · 2004. Jún. 14. (H), 14.48
Az alter tényleg nem rossz, de arra a fejlesztőnek van szüksége, nem a kész programnak. A kettő nem ugyanaz.

/sunz