02/12/2015 10

SQL Injection Nedir ve Nasıl Korunulur ?

Herkese merhaba bu yazıda sizlere SQL injection hakkında bilgi vereceğim ve bu açıktan nasıl korunulacağını anlatacağım. İlk olarak SQL Injection nedir ondan bahsetmek isterim.

Sql Injection Veritabanımıza sızılmasını sağlayan kodlama hatalarımızdır. Bu hatalar ile saldırgan olan kişi açıklarımızdan faydalanarak veritabanımızın bilgilerini ele geçirir ve istediğini yapar.

Web sayfalarında SQL kodları nasıl çalışır?

Bildiğimiz üzere web sayfaları üzerinden sql kodları ile veritabanı update insert delete gibi işlemleri yapabiliyoruz. Bu işlemler sayfa aracılığı ile yapıyoruz. Genelde SQql işlemlerini kullanıcılar yaparlar. Mesela kulanıcı sayfa üzerinde arama yaptığında bir SQL kodu çalışır. Yani kullanıcılar sayfalarınız aracılı ile SQL kodlarını çalıştırır.

SQL kodları Server taraflı çalışan kodlardır. Yani client kısmında çalışmazlar. Kulanıcıların sayfa üzerindeki yaptığı işlemler server tarafındaki sql kodlarını gönderilen parametreler ile çalıştırır.

Server Tarafında Çalışan Örnek bir SQL Kodu:


kriter= QueryString["arama_kriteri"];
arama_sorgusu = "SELECT * FROM tablom WHERE tag= " + kriter;

Yukarıdaki sorgu ile kullanıcı tarafından gönderilen arama_kriteri adlı değişken ile birlikte bir select sorgusu çalışır. Kullanıcının girdiği değere göre veritabanında istenen tablodan veriler çağrılır ve kulanıcıya gösterilir.Buraya kadar SQL kodlarının nasıl çalıştığını anladıysak bundan sonra SQL In jection olayına bakalım

SQL Injection Nedir ?

Sayfanıza veri girme yöntemiyle sayfalar aracılığıyla SQL kodlarını çalıştıran bir yöntemdir. Yani kişi sayfanıza veri giriyormuş gibi SQL kodlarını girer ve sql kodları sisteminizde çalışır. Sonuç olarak saldırgan kişi amacına ulaşmış olur. Bu sayede kişi tablolarınızda ve veritaanı sisteminizde değişiklikler yapabilir. Ve sisteminizi çökertebilir.

1=1 mantığı ile SQL injection

1=1 demek her zaman doğru anlamına gelir. Yani kişi adminmi değilmi kontrolü yaparken bu sorgu kişi admin olmasa bile kişiyi admin olarak görür ve admin panele giriş yapmasına olanak tanır.

Şimdi şöyle bir örnek düşünelim. Dedim ya admin kontrolü yapan yerde yapacağımız bir kontrol

select * from kullanicilar where type = 'admin'
diye bir sorgumuz olsun. Bu sorgu ile sadece admin olanlar girebilir. fakat bu sorguyu şu hale getirirsek

select * from kullanicilar where type = 'admin' or 1=1

Yukarıdaki hali ile sorguyu herkes girebilir yaptık. Yani şu anda admin felan fark etmez herkes girebilir. İlk yazılan SQL kodunun amacı sadece adminlerin girmesiydi. Saldırganlar bu şekildeki kodları sizin kontrol ettiğiniz sorguya ekleyerek admin panellerinize girmeye çalışır. Bu tarz girişimleri engelemelisiniz.

Şimdi bu işlemin server taraflı sonuçlarına bakalım


select * from kullanicilar where type = 'admin' or 1=1

Burada 1=1 her zaman doğru anlamı döndürür. ve bununla beraber kullanan or ifadeside bu sorgunun sonucunun her zaman doğru olarak döndürmesini sağlar. Ve kişi bu sayede admin olarak giriş yapmış olur.

""="" ile yapılan SQL Injection Saldırıları

Web sitelerinde giriş yapılırken kullanılan = işareti sayesinde bazı SQL sorguları oluşturulur ve bu sorgularla bazı eşitlikleri değiştirip SQL kodlarını çalıştırabiliriz.

Aşağıda Örnek bir kod yazalım


kullanici_adi = getRequestString("k_adi");
sifre = getRequestString("sifre");
sorgu = "SELECT * FROM kullanicilar WHERE kullanici_adi='" + kullanici_adi + "' AND sifre='" + sifre + "'"

İşini bilen bir hacker = veya or ifadelerini yukarıdaki sorguya eklemeye çalışır. Ve kullanıcı girişi gibi yerlerde Bu işlemin başarılı bir şekilde olacağını bilir. Bu sayede kendi sorgusunu yukarıdaki sistemin sorgusuna bindirmeyi başarabilir ve istediği işlemi yapabilir.

Yukarıdaki sorguya belirttiğim ifadeler eklenince sorgu aşağıdaki gibi olur.

SELECT * FROM kulanicilar WHERE kullanici_adi="" or ""="" AND sifre="" or ""=""

Yukarıdaki sql sorgusu ile sonuc her zaman doğru dönecektir. Ve hacker giriş yapmak istediği yere girebilecektir ve amacına ulaşmış olacaktır.

Parçalı Sorgular ile SQL Injection Saldırıları

Neredeyse bütün veritabanı yönetim sistemleri parçalı SQL sorgularını destekler.

Aşağıda bununla ilgili bir örnek bulunmakta :


SELECT * FROM kullanicilar ; Create Database TheCodeProgram;
Yukarıdaki tablo önce kullanicilar tablosundaki verileri çeker ve ardından TheCodeProgram adında bir veritabanı oluşturur. Bu tarz tek satırda noktalı virgül ile ayrılmış kodlara parçalı sorgu denir. Eğer kullanıcı girişi sorgusunda aşağıdaki gibi bir parçalı sorgu eklenirse sonucu görelim.

user_name= getRequestString("UserId");
sorgu = "SELECT * FROM kullanicilar WHERE kullanici_adi= " + user_name;
Yukarıdaki sorguda user_name yazan yere aşağıdaki alan yazılırsa oluşacak sonucu görelim ve sıkıntıyı düşünelim. Yani user_name kısmına aşağıdaki alan yazılacak. 33; Drop Database TheCodeProgram; Bu şekilde oluşan sorguyu tekrar inceleyelim ve sonucunu görelim.

SELECT * FROM kullanicilar WHERE kullanici_adi= 33; Drop Database TheCodeProgram;
Yukarıdaki sorgu ile yapılacak işlemler
  • kullanici_adi 33 olan satırı getir
  • Ve arkasından TheCodeProgram adlı veritaabnını sil.
Yukarıdaki sonuçları gördük ve SQL injection olayının ne kadar tehlikeli olduğunu anlamışızdır diye umut ediyorum.

Peki korunmak için ne yapmamız gerekmektedir?

Bazen bir kara liste ile SQL sozcuklerinin engellenmesi yapılabilir. Bu şekilde SQL ifadesi girildiğinde kullanıcıya yasaklı kelime girdiniz şeklinde bir uyarı verilebilir.

Şu zamanlarda bu çok iyi bir fikir değil bence. Çünkü SQL sorgularında kullanılan noktalı virgül, delete, drop gibi kelimeler heryerde kullanılabilir. Bu yüzden bu yönten çok sağlıklı olmayailir.

Bu yüzden en sağlıklı yöntem SQL kodlarınızı parametreler ile çalıştırmaktır. Parametreler ile kelimeler önce bir süzgeçten geçirilmiş gibi olur ve bu şekilde sisteminize szarar veremez. SQL sorgularında parametreler kullanıldığında parametrelerin değerleri kullanılır. Yani direk olarak kendileri değilde parametrelerin değerleri kullanılacağı için sorgularda çalışmayacaktır.

Aşağıda Parametre kullanımı ile ilgili bir örnek inceleyelim


kullanici_adi = getRequestString("username");
sql_sorgu = "SELECT * FROM kullanicilar WHERE kullanici_adi = @0";
db.Execute(sql_sorgu ,kullanici_adi);

Yukarıdaki sorguya @ işareti ile sıfıncı parametreyi gönder dedik. Parametreleri belirtirlen @ işaretini kullandığımızda unutmayalım. Yukarıdaki sorgu ile SQL yönetim sistemi parametreleri kontrol ederek sorguya ekleyecektir ve SQL sorgusu yazılmış olsa bile veritabanı ile işlemler sağlıklı ir şekilde gerçekleşecektir.

Başka bir Örnek Yapalım


ad = getRequestString("ad");
soyad = getRequestString("soyad");
no = getRequestString("no");
txtSQL = "INSERT INTO kullanicilar(ad,soyad,no) Values(@0,@1,@2)";
db.Execute(txtSQL,ad,soyad,no);
 

Yukarıdaki örnek ile bir SQL sorgusu yazıp bu sorguyu parametreler ile çalıştırmış olduk. Bu sayede SQL injection saldırılarından korunmuş olduk. Yukarıdaki örnekler ASP.NET içindir. Yani .NET temelli dillerde kullanılan şekildi. Aşağıda ise PHP dilinde parametreler ile veri ekleme yani insert komutu bulunmaktadır.


$sorgu = $db->prepare("INSERT INTO kulanicilar (ad,soyad,no)
VALUES (:_ad, :_soyad, :_no)");
$sorgu ->bindParam(':_ad', $isim);
$sorgu ->bindParam(':_soyad', $soyisim);
$sorgu ->bindParam(':_no', $numara);
$sorgu ->execute();
 

Yukarıda PHP dilinde bir sql sorgusu gördük. Bu sayede Parametreler ile PHP dilinde veritabanına veri eklemiş olduk.

Artık SQL injection nedir ve nasıl korunur konusunu öğrendik. SQL injection içeren site kalmasın.

Bu yazımızda bu kadar -- Takipte Kalın

İyi çalışmalar

Burak Hamdi TUFAN


Tags

Share this Post



Post a Comment

Success! Your comment sent to post. It will be showed after confirmation.
Error! There was an error sending your comment.

Comments

    There is no comment. Be the owner of first comment...