|
SQL Injection Ataklarından Nasıl Korunuruz? |
|
Gönderiliyor lütfen bekleyin... |
|
|
Bu
makalemizin konusu başlıktan da anlaşılacağı gibi, web uygulamalarımıza yapılan
saldırılara karşı nasıl önlem almamız gerektiği. Aslında web uygulamamıza yapılabilecek
bir çok saldırı metotları vardır. Bu makalede, bu saldırı çeşidinden biri olan
Sql Injection (Sql Aşılama) ataklarına karşı savunma taktiklerini anlatacağım.
Peki sql injection atakları nasıl yapılır?? Sql Injection atakları, web uygulamalarımızda
yer alan veri girişleri için kullandığımız TextBox form elemanlarının içine
yazılan bazı sql komut deyimlerinin yazılması ile olur.
Web uygulamalarımızın en zayıf bölümü kullanıcı girişlerinin yapıldığı ve sonucunda
yetkilendirme yapıldığı bölümlerdir. Yani login sayfalarıdır. Web uygulamaları
ile ilgilenen herkes mutlaka bir login sayfası yapmıştır. Temel olarak iki tane
TextBox ve bir tane Button yer alır. Kullanıcı TextBox’lara gerekli verileri
girdikten sonra Button’a tıklar ve Button’un OnClick olayı devreye girer. OnClick
olayında ise veritabanına bağlantı gerçekleştirilir, gerekli sorgu komutu yazılır
ve eğer TextBox’lara girilen veriler ile veritabanındaki tabloda yer alan herhangi
bir kayıt eşleştiyse (veya en az bir kayıt döndürüyorsa) bu kullanıcı için web
uygulamasına giriş başarılı olmuştur. Yani kullanıcının Authenticate işlemi
gerçekleştirilmiştir. Aslında her şey düzgün çalıştığını zannederken kötü niyetli
kişiler tarafından web uygulamalarınızın tehdit altında olduğunu farketmezsiniz.
Bende web uygulamaları ile çalışmaya yeni başlarken eğer kod düzgün çalışıyorsa
her şey bitmiş gibi düşünürdüm. Güvenlik kısmını herzaman arka plana atmıştım.
Bazen makelelerimizde esas konuya yoğunlaşmak için bazı güvenlik ilkelerini
ihlal ederiz. Fakat siz uygulamalarınızda güvenlikten asla ödün vermeyin.
Sizlere bu makalede
kötü yazılmış bir kod ve iyi yazılmış bir kodun karşılaştırmasını yapacağım.
Fakat en önce Sql Injection ataklarına karşı koymanız için gereken 5 temel savunma
prensibini bilmeniz gerekir:
Prensipler |
Neler
Yapmalısınız? |
Kullanıcı
girdilerine asla güvenmeyin. |
Tüm
TextBox girişlerinin değerlerini Validator Kontrolleri, Regular Expressions
veya kod ile kontrol edin. |
Veritabanına
asla admin düzeyinde bağlanmayın. |
Veritabanına
gerekli düzeyde kısıtlı erişim ile bağlanın. |
Asla
dinamik Sql sorguları kullanmayın. |
Parametre
göndererek veya Stored Procedure Kullanın. |
Veritabanına
verilerinizi asla açık şekilde yazmayın. |
Verilerinizi
şifreleme algoritması kullanarak veritabanına kaydedin. |
Web
uygulamalarınızda meydana gelebilecek istisnalarla(Exceptions) veya hatalarla
ilgili bilgileri en düşük düzeyde kullanıcıya aktarın. |
Web
uygulamalarınızda meydana gelebilecek olası her hataya karşı özel bir hata
sayfası hazırlayın. |
Şimdi sıra geldi
web uygulamalarınızı nasıl yazmanız ve yazmamanız gerektiğine.
login.aspx sayfamızda yer alan Button’un OnClick olayına şu şekilde kod yazılmış
olduğunu farzedelim.
private
void
Button1_Click(object sender, System.EventArgs
e)
{
string strCnx = ConfigurationSettings.AppSettings["BadconnStr"];
SqlConnection conn
= new SqlConnection(strCnx);
conn.Open();
SqlCommand cmd = new
SqlCommand();
cmd.Connection = conn;
cmd.CommandText =
"Select * From users Where username = ’"+ txtusername.Text +"’AND password
= ’"+ txtpassword.Text +"’ ";
SqlDataReader dr;
dr = cmd.ExecuteReader();
if(dr.Read())
{
FormsAuthentication.RedirectFromLoginPage(txtusername.Text,false);
}
else
{
ErrLabel.Text = "Başarısız İşlem";
}
} |
Eğer kullanıcı
kendi kullanıcı adı ve şifresini girerse her şey normal şekilde sürer. Fakat
eğer iyi yazılmamış bir login sayfasında aşağıdaki gibi bir ifade girilirse
ne olur görelim.
’or 1=1--
şeklinde bir Sql ifadesi
kullanıcı adının girileceği TextBox’a girilir ve şifre kısmına da rastgele bir
değer girilirse, veritabanımızdaki tabloda böyle bir kullanıcı olmasa bile yetkilendirme
işlemi başarılı olacaktır. Çünkü ’or 1=1-- ifadesinin TextBox’a girilmesi sonucu
sorgu ifadesi şu şekle dönüşmüş olur.
Select
* From users Where username = ’ ’or 1=1--’ AND password = ’"+ txtpassword.Text
+"’
Kullanıcı adını yazdığımız
TextBox nesnesine girilen ’or 1=1-- ifadesinde yer alan -- işaretlerinin anlamı;
-- işaretlerinden gelen sonraki ifadeleri yoksay olacaktır. Yani sonuç olarak
ifademiz;
Select
* From users Where username = ’ ’or 1=1--
şekline dönüşecektir.Bu
ifadede yer alan or 1=1 ifadesi sürekli doğru sonucu vereceğinden sonuç olarak
sorgu işlemi bir kayıt döndürecektir. Bizim if döngümüzde yer alan dr.Read()
ifadesi de true değerini alacağından if deyimi çalıştırılacak ve kullanıcı Authenticate
işlemini başarı ile geçecektir.
Peki bu Sql Injection saldırısının çalışmasını sağlayan hatalar neydi? Kodumuzu
satır satır inceleyelim.
string
strCnx = ConfigurationSettings.AppSettings["BadconnStr"];
SqlConnection conn = new SqlConnection(strCnx); |
bu ifadede BadconnStr
değerini Web.config sayfamızdan almaktayız. Web.config sayfamızda yer alan ConnectionString
ifademiz şu şekildedir.
<appSettings>
<add key="BadconnStr" value="server=localhost;uid=sa;pwd=;database=veritabani;"></add>
</appSettings> |
Bu ConnectionString
ifadesindeki hata veritabanına sa olarak bağlanmamızdır. Hiçbir zaman veritabanına
sa kullanıcısı olarak bağlanmayın. Çünkü sa veritabanı üzerinde çok yüksek haklara
sahiptir. Oysa bize gerekli olan sadece SELECT
sorgusu.
Diğer bir hata ise sorgu işleminin dinamik olarak yapılması. Eğer bu şekilde
dinamik olarak SQL sorguları yaratılırsa yukarıda girilen ’or 1=1-- ifadesinin
girilmesi ile çok büyük güvenlik açıklarına neden olursunuz. Peki ne yapacağız.
Yukarıda bahsettiğim prensiplere göre parametre olarak veri göndermeli veya
Stored Procedure kullanmalıyız.
Aslında yukarıda TextBox’lara girilen değerleri de kontrol etmemiz gerekir.
Yine aynı şekilde TextBox’ın MaxLength özelliğinin mutlaka kısıtlanması gerekir.
Yani TextBox’lara sınırsız karakter girilmesini önlemeliyiz. TextBox’lara girilebilecek
özel karakterleri de kontrol etmeliyiz. Yani ’ " - + # % & gibi bir
çok karakterlerin girilmemesini sağlamalıyız.
Sadece ’or 1=1-- ifadesinden farklı Sql Injection saldırıları da olabilir. Örneğin
yine kullanıcı adını girdiğimiz TextBox nesnesinin içine,
’;
UPDATE users SET password = ’deneme’ WHERE username = ’mehmet’ --
ifadesi de girilebilir.
Peki bu Sql Injection ne gibi zararlara neden olur?
Bu ifade ile çoklu Sql deyimleri noktalı virgül yardımı ile aynı anda çalıştırılabilir.
Bu ifade ile users tablosunda yer alan kullanıcı adı mehmet olan kişinin şifresini
deneme olarak değiştiriyor. Eğer yukarıdaki gibi kötü yazılmış bir kod varsa bu
işlem başarı ile gerçekleştiriliyor. Yine aynı şekilde buna benzer bir ifade ile,
veritabanında yeni kullanıcılar yaratılabilr, bir tablo silinebilir, veya herhangi
bir stored procedure yazılarak çok farklı işlemler gerçekleştirilebilir. Bunu
önlemenin yolu veritabanına bağlantı yaptığımız ConnectionString’inde yer alan
user’a sadece ve sadece gerekli izinler verilmelidir. Örneğin, burada user’ın
sadece SELECT ifadesi için izin verilseydi hiç bir sorun olmayacaktı.
Şimdi daha güvenli login işleminin nasıl gerçekleşeceğini görelim.
Daha Güvenli
Login Sayfamız
Öncelikle sayfamızın
tasarım kısmının neye benzediğine bakalım. Daha iyi görebilmek için şeklin üzerine
tıklayıp büyütebilirsiniz.
LOGIN Butonuna tıkladığımızda çalışacak kodu görmeden önce Web.config dosyasında
yer alan ConnectionString ifadesini görelim.
<appSettings>
<add key="BetterconnStr" value="server=localhost;uid=serkan;pwd=deneme;database=aspnedir;"></add>
</appSettings> |
Button’umuzun OnClick olayında çalışacak kod ise şu şekildedir.
private
void
Button1_Click(object sender, System.EventArgs
e)
{
string strCnx = ConfigurationSettings.AppSettings["BetterconnStr"];
SqlConnection conn
= new SqlConnection(strCnx);
conn.Open(); SqlCommand
cmd = new SqlCommand();
cmd.Connection = conn;
cmd.CommandType =
CommandType.StoredProcedure;
cmd.CommandText =
"UserControl";
SqlParameter prm;
prm = new
SqlParameter("@username",SqlDbType.NVarChar,50);
prm.Direction = ParameterDirection.Input;
prm.Value = FormsAuthentication.HashPasswordForStoringInConfigFile(txtusername.Text,"SHA1");
cmd.Parameters.Add(prm);
prm = new SqlParameter("@password",SqlDbType.NVarChar,50);
prm.Direction = ParameterDirection.Input;
prm.Value = FormsAuthentication.HashPasswordForStoringInConfigFile(txtpassword.Text,"SHA1");
cmd.Parameters.Add(prm);
SqlDataReader dr;
dr = cmd.ExecuteReader();
if (dr.Read())
{
FormsAuthentication.RedirectFromLoginPage(txtusername.Text, false);
}
else
{
ErrLabel.Text = "Başarısız İşlem";
}
} |
Yukarıda makalenin
ilk başında bahsettiğim 5 temel prensibin hepsi bu login işleminde uygulandı.
TextBox nesnelerine girilebilecek max karakter sayısının kısıtlanması ile çalışabileck
Sql deyimleri girilemez. Aynı şekilde RegularExpressionValidator ifadeleri ile
özel karakterlerin girilmesi önlenlenmiş oldu. Yine ConnectionString ifademizde
benim yarattığım bir kullanıcı ile bağlanılıyor. Bu kullanıcıya sadece StoredProcedure’leri
çalıştırılmasına izin veriliyor. Böylece başka herhangi bir sql komutunun çalışmasına
olanak tanınmıyor. Çünkü veritabanına bağlanan kullanıcının yapabildikleri kısıtlanmıştır.
SqlCommandType’in özelliği Stored Procedure olarak ayarlanmış ve böylece dinamik
SQL ifadelerinin kullanılması engellenmiş olur. Stored Procedure’e aktarılan
parametrelerde şifrelenerek veritabanında, şifrelenmiş olarak duran kayıtlarla
karşılaştırlır.
Elbette web uygulamasının içerisinde, login sayfasından farklı sayfalarda yer
alan TextBox nesneleri ile kötü niyetli kullanıcılar veritabanımıza dolayısıyla
web uygulamamıza zarar verebilirler. Örneğin, herkesin bildiği site içerisinde
arama yapabilmemizi sağlayan TextBox nesnelerine girilen değerlerde kontrol
edilmelidir.
Bu makalenin içerisinde yer alan kodları daha iyi anlayabilmek için, makale
içinde geçen bazı konuları (FormsAuthentication, Verileri Şifreleme, RegularExpressionValidator,
Stored Procedure) yine aspnedir.com sitesinden okumanızı tavsiye ederim.
Örnek Uygulama : SQL
Injection
Makale:
SQL Injection Ataklarından Nasıl Korunuruz? ASP.NET Serkan Karaarslan
|
|
|
-
-
Eklenen Son 10
-
Bu Konuda Geçmiş 10
Bu Konuda Yazılmış Yazılmış 10 Makale Yükleniyor
Son Eklenen 10 Makale Yükleniyor
Bu Konuda Yazılmış Geçmiş Makaleler Yükleniyor
|
|