SQL injection ve Korunma Yöntemleri

SQL injection yapmak korunmak çoğu zaman basit bir işlemdir fakat önemli bir konudur. Şimdi basit SQL injection yapmayı sonra farklı korunma yöntemlerini inceleyelim.

SQL injection kötü amaçlı, normalde çalışmaması gereken SQL komutlarıdır. SQL injection ya adres satırından ya da input alanından yapılır. Kötü amaçlı SQL kodu eğer veriler POST ile yollanıyorsa input alanına (genellikle text kutusuna), GET metodu ile yollanıyorsa adres satırına girilir.

SQL injection

Basit bir örnekle SQL injection yapalım. Örneğimizde GET motodu kullanacağız. Veritabanı olarak Mysql, script dili olarak da php kullanacağız. Öncelikle verilerimizin bulunduğu tabloya göz atalım. Tablomuzun adı "people":

sql injection ve korunma yöntemleri

Şimdi bu verileri GET metodu ile alacak PHP scriptimizi yazalım:
 
// vetitabanına bağlan
$conn = mysql_connect("localhost","root","");
mysql_select_db("test",$conn);

// sorguyu hazırla
$sql= "SELECT * FROM people WHERE id = '$_GET[id]'";

// sorguyu çalıştır
$result= mysql_query($sql,$conn);

// verileri al ve göster
while ($row=mysql_fetch_array($result))

{
 echo $row['isim']." ";
 echo $row['soyisim']."<br />";
}
echo "<br />";
echo "çalıştırılan sorgu : ".$sql;
 
"sql.php" olarak kaydettiğimiz bu PHP scriptini web browserda açıp aşağı şekildeki gibi adres satırı sonuna id numarası 1 olan kişiyi gösterecek "?id=1" ekleyelim:

sql injection ve korunma yöntemleri

Şimdi SQL injection kodumuzu yazalım ve çıktıyı alalım:

sql injection ve korunma yöntemleri

SQL injection kodumuzu inceleyelim: 'OR 'x'='x
ilk ' tek tırnak karakteri id değerine boş değer yollamamızı sağlıyor. Fakat sorgunun boş değer döndürüp hata vermesini engellemek için OR komutu 'x' = 'x ifadesi ile birleştirilerek her zaman doğru sonuç döndürecek kriter ekleyerek tüm kişileri görebiliyoruz. Çalışan sorgu ifadesini incelersek ne demek istediğimi anlayabilirsiniz.

Bunun haricinde farklı sorgular da yollamak mümkün. Eğer veritabanı kullanıcısı yetkileri yeterliyse SELECT sorgusu dışında DELETE, INSERT , UPDATE ve diğer bir çok zararlı SQL kodunu çalıştırmak mümkün. Tüm olay doğru sql injection yapmaktan geçiyor.


SQL injection korunma yöntemleri

SQL injection konusunua kısaca değindikten sonra şimdi SQL injection korunma yöntemlerini inceleyelim. SQL injection yapmaktansa bundan korunmak daha önemlidir.

SQL injection'dan kurtulmanın bir çok yolu var. Bunları listeleyip daha sonra inceleyelim.
Genel SQL injection korunma yöntemleri:
  • GET ya da POST ile yollanan verileri doğrulamak
  • Gönderilen verileri filtrelemek
  • SQL Parametresi kullanmak (Prepare yapmak)
  • Kullanıcı yetkilerini kısıtlamak
  • Güvenliği test etmek, gözden geçirmek, önemli verileri encrypt etmek
Şimdi bunları inceleyelim:

SQL injection kurunma yöntemi 1: GET ya da POST ile yollanan verileri doğrulamak

Doğrulama yapmak basittir. Örnekle aşağıdaki tablodaki karakteri içeren her hangi bir input alanı varsa kullanıcıyı uyarar tekrer veriyi girmesini sağlanabilir. Sakıncalı karakterler:
Sakıncalı karakterler Anlamı
; sorgu ayıracı
' karakter veri ayıracı
-- Yorum ayracı
\* Yorum ayracı 2
Yukarıdaki tablodaki her hangi bir karakter içeren varsa girdi kabul edilmemelir.
Bununla ilgili basit bir örnek yapalım. Aşağıdaki PHP kodu girdiyi Regular Expressions ile doğruluyor. Doğrularsa "doğrulandı" diye ekrana yazdırıyor. PHP ile girdi doğrulama kodumuz:
 
 // Girdiyi  alıyoruz. 
//( örnek olduğu için girdiyi elle giriyoruz)
$input="Bu girdi kontrol edilecek..'";
// Regular expression ile girdi kontrol (doğrulanıyor) ediliyor.
if (preg_match("/[\-]{2,}|[;]|[']|[\\\*]/", $input))
 echo "zararlı karakterler var";
else 
 echo "doğrulandı"; 
Yukarıdaki kodda input değerimiz içinde dikkatle bakarsanız ' tek tırnak ayıracı bulunuyor. By yüzden bu girdi doğrulanmayacaktır.

SQL injection yapmak için kullanılan özel karakterleri daha sorgu çalıştırılmadan girdiyi yukarıdaki örneğe benzer şekilde doğrulayıp soruyu çalıştırabiliriz.
Aynı doğrulama yöntemini ASP.NET'de de Regular Expressions ile yapabiliriz.

SQL injection kurunma yöntemi 2: Gönderilen verileri filtrelemek

Seviyeyi biraz daha arttırıp istediğimiz karakterler dışındaki karakterleri filtreleyebiliriz. Bunu yine Regular Expresions kullanarak yapalım. Örnek PHP kodumuz:
 
// Girdiyi  alıyoruz. 
//(örnek olduğu için girdiyi elle giriyoruz)
$input="34'; DELETE FROM test";
// Regular expression ile girdiyi filtreliyoruz
// 0 ve 9 arasında olmayan tüm karakterleri siler
$input=preg_replace("#[^0-9]#",'', $input);
// aşağıdaki satır ekrana 34 yazdırır
 echo $input;
  
Bu örneğimizde filtreleme yaparak direk olarak SQL injection koruması yapmış olduk.

SQL injection kurunma yöntemi 3: SQL Parametresi kullanmak (Prepare yapmak)

Prepere işlemini hep programlama diliyle hem de Mysql gibi veritanabanlarında yapmak mümkün.Biz örneklerimizde programlama ile yapacağız. Prepare ile sorgularımızı parametre alacak şekilde hazırlıyoruz daha sonra parametreleri bağlayayıp sorguyu çalıştırıyoruz. Bu yöntem bana göre en çok kullanılması gereken yöntemdir. Prepare işlemleri özellikle birden çok paramatre alan sorgular için daha uygun. PHP ile Prepare yapalım. Örekte PHP 5.1+ ile yüklü gelen PHP Data Objects (PDO) extension'ı kullandık.
 
 // Girdiyi  alıyoruz. 
//(örnek olduğu için girdiyi elle giriyoruz)
$input=1;
// veritabanına bağlanıyoruz (PDO : PHP Data Objects (PDO) extension )
// PDO extension PHP 5.1 ile otomatik olarak yüklü olarak geliyor.
$dbh = new PDO('mysql:host=localhost;dbname=test', 'root', '');
// prepare işlemi yapıyoruz
$stmt = $dbh ->prepare('SELECT * FROM people WHERE id = :id');
// bind işlemiyle verimizi bağlıyoruz
$stmt->bindParam(':id', $input);

// çalıştırmayı deneyip hata almazsak çıktıyı gösteriyoruz
if ($stmt->execute()) {
  while ($row = $stmt->fetch()) {
    echo "<pre>";
    print_r($row);
	echo "</pre>";
  }
}
 
Yukarıdaki kodun çıktısını çalıştırdığımda şöyle aldım:

sql injection ve korunma yöntemleri

PHP ortamında çalışıyorsanız Prepare ve Execute yapmanızı sağlayan ücretsiz dağıtılan farklı paketler mevcut. Bunlardan birisi PEAR Package'dır. pear package (prepare işlemleri yapabilirsiniz kururak) (sql injection ve korunmak) linkinden indirebilirsiniz.

Eğer ASP.NET ortamında çalışıyorsanız aşağıdaki gibi prepare ve execute işlemlerini yaparak sql injection korunması sağlayabilirsiniz.
 
 // id numarasını GET metodu ile alıyoruz
  string id = Request.QueryString("id");
 // SQLcommand nesnesi oluşturuyoruz
  SqlCommand cmd = new SqlCommand("SELECT * FROM people WHERE id = @p_id");
  // parametre tipini belirliyoruz
  var param = new SqlParameter("p_id", SqlDbType.Int);
  //parametre değerini giriyoruz
  param.Value = 1;
  // parametreyi bağlıyoruz
  cmd.Parameters.Add(param);
 
Yukarıdaki komut güvenle çalıştırılabilinir.

Prepare işlemlerini buna benzer şekilde kullanarak SQL injection korunması sağlayabilirsiniz. Her ne kadar Prepare işlemleri PHP ve ASP.NET ortamında farklı olsada aynı mantığı uygulayabilirsiniz. Bu arada Stored Procedures kullanarak Prepare yaparsanız en güzel SQL injection korumasını yapmış olursunuz.

SQL injection kurunma yöntemi 4: Kullanıcı yetkilerini kısıtlamak

Bu yöntem diğer yöntemlerden biraz farklı. Sadece kullanıcının SELECT, UPDATE, INSERT, CREATE vb. yetkileri elinden alarak korunma sağlanmış olur. En mantıklısı eğer INSERT, UPDATE gibi DML (Data Manipulation Language ; veri değiştirme dili) kullanılmıyorsa kullancıyı sadece SELECT ile kısıtlandırmak güzel bir çözüm olacaktır.

SQL injection kurunma yöntemi 5: Güvenliği test etmek, gözden geçirmek, önemli verileri encrypt etmek

Yapılan SQL injection korunma yöntemlerini sağladıktan sonra kendi sisteminize ilk başta kendiniz sızmalısınız. Şüphe duymalısınız. Kullandığınız yöntemlere güvenmemelisiniz.
Hiçbir zaman yüzde yüz güvenli bir ortam olmadığını düşünecek olursanız güvenliği her zaman elden bırakmamak gerekir. Zira farkında olunmadan bir açık bırakılırsa neler olacağı belli olmaz.

Şifreler, Kredi Kardı gibi önemli verilerin saf hali değil md5 gibi algoritmalar kullanarak encrypt edilip veritabanına girilmelidir.


SQL injection korunma tekniklerinin hepsini kısaca anlatmaya çalıştım. Umarım faydalı bir yazı olmuştur.
yazan Zülküf Küçüközer tarih   25th August 2009
primary key words  Sql injection | Korunma yöntemi | Php okunma  24601
secondary key words  Prepare
writing Osman y?lmaz writing 18th December 2010
Güzel Anlatım olmuş Teşekkürler paylaşım için
writing hakan writing 14th February 2011
SQL injection kurunma yöntemi 4: Kullanıcı yetkilerini kısıtlamak Kullanıcı yetkilerini kısıtlamak için ne yapmam lazım tam olarak nasıl konu açarsanız sevinirim
writing rahim can writing 3rd September 2012
Güzel Makale Olmuş , Teşekkrüler
writing Ibrahim writing 22nd April 2013
Tesekkürler.
writing zafer writing 22nd June 2013
ASP varmi?