ANASAYFA | BLOG | SORU CEVAP | REFERANSLARIM | DOWNLOAD | HAKKIMDA | İLETİŞİM | ARAMA
SQL INJECTION

SQL Injection

Uygulamalarımızda kullanıcı doğrulaması yada herhangi bir kontrol için SQL sorgusu gönderdiğimizde bu sorguyu gönderme biçimimize göre sistemimizde güvenlik açığı olabilir. Bu açıklık SQL-injection olarak adlandırılmaktadır. Bu açığı kullanarak

  • Sisteme giriş yapılabilir
  • Yetkisiz alanlara erişilebilir
  • Sisteminizdeki veritabanı yapısı değiştirilebilir…

FK-gizle

 

Örnek olarak bir kullanıcı giriş sistemini ele alalım, Genel olarak sistemlerin girişinde aşağıdaki gibi kullanıcıAdı ve Şifre istenmektedir.
 

sql_injection

 Başlangıç seviyedeki yada SQL-injection ı bilmeyen kullanıcılar sisteme girişi kodlarken, genel mantık olarak
SQL deki kullanıcı adı ilk TextBox a eşitse VE SQL deki Şifre ikinci TextBox a eşitse

Select * from tbKullanici
where kAd='" + kAd + "' AND kSifre='" + kSifre + "'

Şeklinde bir sorgu gönderip bunun sonucunda dönen satır sayısı 0 dan büyükse sisteme gir şeklinde bir kodlama yaparlar. Böyle bir kodlama da kullanıcı TextBox lara ne değer girerse bu direk olarak SQL sorgusu olarak çalıştırılacağından kötü niyetli birisi burdan sisteminize sızarak veritabanınızda istediği herşeyi yapabilir desem heralde yanlış olmaz. Ne demek istediğimi daha iyi anlatmak adına örnek olarak aşağıdaki gibi bir giriş yapıldığını düşünelim
 

sqlinjection


Text lere yukarıdaki gibi girdiğimizde SQL e giden sorgu şu şekilde olacaktır

Select * from tbKullanici where kAd='' OR 1=1 /*' AND kSifre='*/ --'

Bunu daha derinden inceleyecek olursak

kAd='' OR 1=1 kısmına yazdığımız  OR 1=1 ile kullanıcı adını bilmesek bile 1 herzaman 1 e eşit olacağından kullanıcı adını bilmeden girişi sağlamış olduk

/*' AND kSifre='*/ --'  kısmında ise şifre bölümü yoruma alınmış ve dewamı ise -- ile yorum olarak belirtilmiştir. Bu şekilde bir giriş ile parametresiz sisteme giriş yapabilir, tablo silebilir, istediğiniz değişikliği yapabilirsiniz

burada yapılacak şey saldıranın isteğine göre şekillenir. yukarıdaki gibi sisteme girmenin başka bir yolu ise aşağıdaki gibi olabilir, Sizde sorguyu istediğiniz gibi şekillendirerek farklı değerlerle giriş yapabilirsiniz

sqlinjection

 

Yada sisteme zarar vermek isteyen birisi örneğin bir tablonuzu silebilir, kaldırabilir, yeni tablo ekleyebilir, veri girişi yapabilir... tabi bu işlemler için tablo ismini de bilmesi gerekir ama sisteme basit bir kullanıcı hesabıyla dahi girmiş olsa bile sql sorgusu ile bütün tablo isimlerini öğrenmek de mümkün. Şimdi basit bir örnekle örneğin sistemimizde tbFaruk isminde bir tablo olduğunu düşünelim. Saldıran kişi bu tabloyu silmek isterse aşağıdaki gibi bir metin girerek bunu başarabilir

sqlinjection

Select * from tbKullanici where kAd='' OR 1=1;
DROP TABLE tbFaruk /*' AND kSifre='*/ --'

Böyle bir giriş ile tbFaruk tablosu kaldırılmış olur. Saldıracak kişi burdaki ; den sonra istediği SQL Script ini yazarak veritabanınızı değiştirebilir

 

Kodlarken SQl injection tehlikesi altında olan örnek kodlama aşağıdaki gibi bir yapıdadır

string kAd = txtKullaniciAdi.Text;
string kSifre = txtSifre.Text;
DataTable tbl = new DataTable();
string sql = "Select * from tbKullanici where kAd='" + kAd + "' AND kSifre='" + kSifre + "'";
SqlDataAdapter adap = new SqlDataAdapter(sql, conn);
adap.Fill(tbl);
if (tbl.Rows.Count > 0)
{
    //yapılacak işlem
    // diğer sayfaya geçiş vs...
    MessageBox.Show("!!!Sisteme Girildi!!!");
}

Bunun yerine parametre göndermeli bir yapı tercih etmemiz gerekir. Böylece SQL-injection dan kaynaklı güvenlik açığını da ortadan kaldırmış oluruz. Buna örnek güvenli bir kod yapısı ise aşağıda belirtilmiştir

 
conn.Open();
string sql = "Select * from tbKullanici where kAd=@parametre1 AND kSifre=@parametre2";
SqlCommand command = new SqlCommand(sql,conn);
command.Parameters.AddWithValue("@parametre1", txtKullaniciAdi.Text);
command.Parameters.AddWithValue("@parametre2", txtSifre.Text);
SqlDataReader dr =command.ExecuteReader();
// isterseniz de datatable a aktararak kullanabilirsiniz
DataTable tbl = new DataTable();
tbl.Load(dr);
 
if (tbl.Rows.Count > 0)
{
    //yapılacak işlem
    // diğer sayfaya geçiş vs...
    MessageBox.Show("!!!Sisteme Girildi!!!");
}
 
conn.Close();

 

Bu şekilde parametreli bir yapı kullanarak saldırıların ve yetkisiz işlem yapmak isteyenlerin önüne geçmiş, onları engellemiş olursunuz. Parametreli güvenli sistemi kullandığınızda yukarıdaki saldırı text lerini girseler dahi sistem bunu kabul etmeyecektir

 

Sistemlere giriş illaki TextBox lar ile değil session ile, queryString ile vs... de yapılabilir. Eğer buralardaki metni direk yukarıdaki güvensiz yöntem ile sql sorgusuna yazarsanız yine aynı şekilde sql injection ile karşılaşacaksınız ve sisteminizde güvenlik açığı olacaktır

Yada başka bir örnek inceleyecek olursak mesela kitap numarası yada öğrenci numarası girildiğinde bir tabloya ilgili kişinin yada kitabın bilgilerini döken bir uygulama modülümüz olduğunu düşünelim

string sql = "Select * from tbKisi where kisiNo=" + txtKisiNo.Text;

sqlinjection

Kullanıcının sadece bir kişi yada sadece bildiği kişi numaralarını görebileceği bir sistemde (yukarıdaki sistem basit anlamda olayı anlatmak için tasarlanmıştır, buraya bir GUID vs gibi yapı ile daha güvenli bir sistem de planlanabilir ama burda asıl konumuz SQL injection olduğundan basit bir örnek ele alınmıştır) kullanıcı KişiNo yerine aşağıdaki gibi bir text girdiğinde bütün sistem kayıtları dökülecektir

sqlinjection


Select * from tbKisi where kisiNo=127 OR 1=1
 

 




Diğer Yazılarımdan Seçmeler...