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.
select * from kullanicilar where type = 'admin'
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.
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;
SELECT * FROM kullanicilar WHERE kullanici_adi= 33; Drop Database TheCodeProgram;
- kullanici_adi 33 olan satırı getir
- Ve arkasından TheCodeProgram adlı veritaabnını sil.
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
Comments