ASP.NET Security Yazı Dizisi

ASP.NET ile SQL Enjeksiyondan korunmak...



Bilindiği üzere güvenlik her şeyin başında gelmelidir. Sistemimizi kodlarken her şeyin yolunda gitmesi bizim içimizin rahat olmasını sağlar fakat her zaman yazdığımız kodun doğru çalışması yeterli olmuyor.

Vereceğim örneği sistemimiz üzerindeki giriş sayfalarında yaptığımız olayın mantığından bahsederek açıklayayım.

Giriş sayfalarındaki en basit mantık 2 adet textbox girişi (genellikle birisi kullanıcı adı diğeri de şifre için kullanılır), 1 tane de sayfanın post edilmesi için bir butondur. Kodlama mantığı ise; textbox’lara girilen değerlerin buton’a basıldıktan sonra dinamik bir Sql sorgusu ve herhangi bir veri okuma yöntemiyle {genellikle bu iş için DataReader -MSSQL için SqlDataReader daha uygundur- kullanılır } kullandığımız veritabanı üzerindeki verilerle eşleştirilip sistemde sadece kullanıcıların görebileceği alana geçiş yapılır. Buraya kadar her şey mantığa uygun ve sorun yok. Veritabanında kayıtlı olan kullanıcı bu şekilde giriş yapabiliyor. Peki ya bu durumun istismarı söz konusu olursa o zaman ne yapacağız? İlk önce bu sorunun cevabı için bu durumun nasıl istismar edilebileceğini açıklamak gerekir. Bunu örnek vererek açıklayayım.

Varsayımlarımızdan bahsetmek gerekirse;

1- Kullanıcı Adı girişimizin yapıldığı textbox’ın id değeri txtKullaniciAdi,

2- Şifre girişimizin yapıldığı textbox’ın id değeri txtSifre,

3- Veritabanımızın adı CyberSecurity,

4- Veritabanımızda kullanıcılarınızın verilerinin saklandığı tablo adı uyeler

5- Veritabanımızda uyeler adlı tablo içerisinde kullanıcı isimlerinin saklandığı kolon adı kullanici_adi

6- Veritabanımızda uyeler adlı tablo içerisinde kullanıcı şifrelerinin saklandığı kolon adı sifre

7- Dinamik Sql sorgumuzun "Select * from uyeler where kullanici_adi = ’" + txtKullaniciAdi.Text + "’ and sifre = ’" + txtSifre.Text + "’ " şeklinde olduğunu varsayalım.

Şimdi de yukarıdaki varsayımlara uygun bir sistemde bu durumun nasıl istismar edildiğine geçelim.

Buraya kadar düzgün bir şekilde işleyen sistemimize ufak bir deneme yapalım. Kullanıcı Adı girişine aşağıda belirttiğim ifadeyi girelim bakalım ne olacak ?

’or 1=1--

Bu şekilde bir giriş yaptığımızda doğacak sonuçları açıklayalım.

Kullanıcı Adı alanına bu giriş yapıldığı taktirde dinamik olarak kullandığımız Sql sorgumuz şu şekli alacaktır.

"Select * from uyeler where kullanici_adi = ’’or 1=1--’ and sifre = ’" + txtSifre.Text + "’ "

Sorgumuz bu hale geldikten sonra bir sifre yazmaya gerek kalmadan sisteme giriş yapılabilir.

Aslında sorgumuzun çalışan kısmı yukarıda belirttiğim kadar bile değil.

Sorgumuz "Select * from uyeler where kullanici_adi = ’’or 1=1--’ şeklini alıyor. Neden diye soranlar için açıklayayım.

’or 1=1-- ifadesinin sonunda bulunan -- işaretleri, buradan sonra gelen sorguyu yok saymak anlamına geliyor.

Peki neden ’or 1=1-- yazdık? Burada verimiz "veya 1=1 eşitliğini sağla" anlamına geliyor. Bu da bizim oraya girdiğimiz değerin hatasız çalışmasını sağlayacaktır.

Bundan nasıl korunuruz?

İlk yapmamız gereken textbox’lara girilen değerlerin kontrolünü yapmak olacaktır. Girilen değerler sadece bizim izin verdiğimiz değerler olmalıdır. Aslında bu iş için aklımda çok farklı bir yöntem daha var fakat yoğunluktan dolayı üzerinde çalışma fırsatı bulamadım. Eğer işe yararsa aklımdaki yöntemi de en kısa zamanda sizlere açıklayacağım. Giriş yapılacak alanların değerlerini dinamik bir şekilde vermekle ilgili bir şeyler düşündüm ama ne derece etkili olacağı hakkında şu an için bir fikrim yok.

Textbox’lara girilen değerleri nasıl kontrol edeceğiz?

Tabii ki RegularExpressionValidator nesnesi ile yapacağız bu işlemi.RegularExpressionValidator nesnesi üzerinde yapmamız gereken tek şey ValidationExpression özelliğine girişine izin vereceğimiz karakter aralıklarını belirtmektir.Örnek vermek gerekirse bu özelliğe atadığımız değerler "^([a-z]|[A-Z]|[0-9]){3,15}$" şeklinde olduğunda textbox’a girilen değerler a-z, A-Z, 0-9 aralığındaki değerler olacaktır.Atanan değerde belirttiğim {3,15} ise textbox’a girilen karakter sayısı ile ilgilidir.Özelliğini bu şekilde atadığımız textbox’a 4 karakterden küçük, 15 karakterden büyük değer giremeyiz.Girdiğimiz taktirde ErrorMessage özelliğine atayacağımız değer ekrana yansıyacaktır ve post işlemi yapılmayacaktır.

Bu yazımın sonuna gelmiş bulunmaktayım. Güvenlik yazılarım seri halinde devam edecektir. Sadece bu yazımdakiler güvenliğimiz için tek başına yeterli olmayacaktır. Bunun yanında yapmanız gerekenleri de diğer yazılarımda anlatacağım. Mesela bu yazıda dinamik Sql cümleleri yerine stored procedure kullanmayı anlatmadım yada ConnectionString güvenliğini anlatmadım. Şimdilik bu kadar. Bunları özümsedikten sonra diğer yazılarımı okumanızı tavsiye ederim. Her şey sırasıyla olursa istediğiniz bilgiyi daha kesin bir şekilde öğrenebilirsiniz.

ASP.NET Connection String güvenliği hakkında...



ASP.NET Security yazı dizimizin ikinci makalesinde sizlere ConnectionString ( bağlantı cümleciği ) güvenliğini nasıl sağlayacağımızdan bahsedeceğim. Anlattıklarımı MSSQL üzerinde anlatacağım.

ConnectionString nedir ?

Bağlantının yapılabilmesi için gerekli olan : hangi ana makine’ye bağlantı yapılacağını, o ana makinedeki hangi veritabanına bağlanacağımızı, o veritabanına bağlanmak için gerekli olan kullanıcı adı ve şifresi gibi bilgilerin tutulduğu bir kod parçasıdır.

Örnek bir ConnectionString :

“Data Source = localhost; Initial Catalog = Northwind; Integrated Security = SSPI;” şeklindedir.

Bu cümleciği biraz daha açalım;
1- “Data Source = localhost” kısmında veri kaynağı olarak yerel makinemizi belirttik. Cümleciğimizde “localhost” yerine ip adresi de yazılabilir.

2- “Initial Catalog = Northwind” kısmında hangi veritabanına bağlanacağımızı belirttik. Buradaki “Northwind” MSSQL de standart veritabanları arasında yer aldığı için Northwind veritabanını örnek verdim.

3- “Integrated Security = SSPI” kısmında da bağlantı güvenliğinin ne şekilde yapılacağını açıkladık. Bu cümleyi yazarsak Windows Authentication seçeneğini kullanarak bağlanmış oluruz. Yani kullanıcı adı ve şifre girmeyiz.

Kafanızda kullanıcı adı ve şifre girmeyeceksek güvenliği nasıl sağlarız gibi bir soru oluşması çok doğaldır. O zaman bu şekilde olan bir cümleciği hangi durumlarda kullanmamız daha uygundur ? sorusunun yanıtını aramalıyız. Böyle bir cümleyi kendi makinenizde projeyi geliştirirken yapabilirsiniz. Bunun projeyi çalıştırırken size performans olarak geri döneceğini unutmamalısınız ama konumuz güvenlik olduğu için performans konusuna daha fazla girmeyeceğim. Bu konuyu ilerleyen yazılarımda işleyeceğim.

Cümlemizin güvenli olması için “Integrated Security = SSPI” yerine “User ID = sa; Password =;” şeklinde kullanabilirsiniz. Bu cümleciği kullandığınız zaman da güvende değilsiniz. Bunun iki nedeni var. Birincisi bu cümleyle bağlantıyı sağlayabiliyorsanız “sa” kullanıcısına şifre atamamışsınız demektir. “sa” ‘ nın açılımı “system admin” ’dir ve veritabanı işlemlerini yaparken en yüksek yetkiye sahip kullanıcıdır. Bu yüzden “sa” kullanıcınıza şifre atamayı asla unutmayın. İkincisi ise “sa” ile veritabanına bağlanmak yine büyük bir tehlike yaratır. Veritabanında en yüksek yetkiye sahip olması sizin için potansiyel bir güvenlik sorunudur. Herhangi birisinin “sa” kullanıcısının şifresini öğrendiği anda sizin veritabanınızın silinme düzeyine kadar tehlikede olduğunu unutmamalısınız. Bu yüzden veritabanına asla “sa” kullanıcısı ile bağlanmamalısınız. Bunun yerine yeni bir kullanıcı yaratıp o kullanıcının yetkilerini düzenlemeniz gerekir. Mesela verdiğiniz yetkilerde veritabanını silme gibi bir yetkisinin olmaması sizin güvenliğiniz açısından çok önemlidir. Büyük bir veritabanı oluşturmak için verdiğiniz emeğin ufak bir hatadan dolayı boşa gitmesini hiçbir programcı istemez.

Bu ana kadar öğrendiklerimizi bir örnek bir bağlantı cümleciği yazarak pekiştirelim;

“Data Source = localhost; Initial Catalog = Northwind;User ID = Dogukan;Password = myPass;” şeklinde güvenli bir cümle hazırlamış olduk. Burada Dogukan yetkileri ayarlanmış kullanıcımız ; myPass ise Dogukan kullanıcısının veritabanına bağlanmak için kullandığı şifredir.

Buraya kadar her şey normal ve projemiz çalışıyor. Hem de güvenli bir şekilde veritabanımıza bağlandık. Her şey bitti mi ? Hayır. Peki projede değişiklik yaparken dikkatimizden kaçan herhangi bir sayfadaki ConnectionString üzerindeki bir harfin hatalı yazılması bize ne gibi sonuçlar doğurur ? Bizim fark etmediğimiz fakat yayına sunduğumuz projemizde başka bir kullanıcının hatalı olarak yazdığımız bağlantı cümleciğinin olduğu kod satırına geldiği veritabanına bağlantı yapmaya çalışan projemiz bir anda duracaktır ve ekrana bağlantı cümleciğinin bu kısmında hata var diye yazacaktır. Yani bağlantı cümleciğimiz olduğu gibi gözükecektir. Şimdi ne olacak ? Eğer kullanıcı kötü niyetli birisi ise bizim ConnectionString’imizden aldığı bilgileri kullanarak bizim veritabanımıza bağlantı yapıp verileri değiştirebilir. Bu da bizim sistemimizdeki bütün verileri ortaya dökecektir. Bunu kimse istemez. Peki böyle bir durumla karşı karşıya kalmamak için ne yapmalıyız ? Yapmamız gereken tek şet ConnectionString’imizi Web.Config dosyamız içerisinde tanımlamak olacaktır.

Bunu nasıl yapacağız ?

Web.Config dosyamızın içerisine girip ( Eğer Web.Config dosyanız yoksa eklemelisiniz. ) appSettings sekmesinin ayarlarını aşağıda belirteceğim şekilde düzenlemelisiniz.





Burada yazanları da açıklayayım:

1- kısmında projemizin ayarlarını belirtiyoruz.

2- ifadesinde ise proje ayarlarında kullanılacak olan yeni bir anahtar ekliyoruz. Burada “myConnectionString” eklediğimiz anahtarın adı ( daha sonra proje içerisinden bu isimle çağıracağız. ) value ise “myConnectionString” isimli anahtarımızın değerini temsil ediyor. Değere atadıklarımız ise bizim ana bağlantı cümleciğimizi oluşturuyor.

3-
kısmında eklediğimiz anahtar tag’ını kapatıyoruz.

4-
kısmında ise eklediğimiz proje ayarları tag’ını kapatıyoruz.

Peki bu Web.Config dosyası içerisinde tanımladığımız ConnectionString’imizi nasıl kullanacağız ? Bunu örnek bir kod ile açıklamaya çalışayım :

string connStr = ConfigurationSrttings.AppSettings[“myConnectionString”];
SqlConnection con = new SqlConnection(connStr);

Şeklinde bir kod satırı ile yaptığım olay ;
1- İlk önce “connStr” adında bir string yaratıp bu string’e myConnectionString isimli anahtarımdaki değeri atadım.

2- Sonra da yeni bir SQL bağlantısı oluşturup bağlantı için kullanacağı cümleyi connStr isimli string’ten almasını sağladım.

Peki neden Web.Config dosyasında tanımlamak daha güvenlidir ?

Web.Config dosyamız dışarıdan okunması engellenmiş bir dosyadır. Çok uç düzeyde işlemler yapılmadığı sürece ( ana makine’ya uzaktan erişim sağlama vs. ) web browser’da Web.Config dosyamız görüntülenmez. Bu yüzden ConnectionString’imizi Web.Config dosyası içerisinde tanımlamak güvenlik için bir adım daha attığımız anlamına gelir.

Aslında bu işlemlerin yanında bir de hata sayfası düzenlemek gerekir. En azından ekrana mevcut hatanın yansımaması karşı tarafın bizim sistemimizde ne gibi işlemler yaptığımızı anlamaması için yapılabilecek işlemlerden birisidir. Bu konuyu daha sonraki yazılarımda sizlere aktaracağım.

Bu yazımız bu kadar. ASP.NET üzerinde güvenliğinizi sağlamak için sadece bu konuda yeterli olmayacaktır. Bu yüzden yazı dizimizi takip etmenizi öneririm. Bunu okudum ve yeter diye düşünmeyin. Çünkü güvenlik için her zaman karşı taraftan bir adım önde olmanız gerekir.

Güvenlik basit bir iş değildir ve projesinde güvenliğe önem veren kişiler gerçek coder’lardan başkaları değildir.

Bu makalemizde Cross-Site Scripting (XSS) saldırılarına karşı nasıl önlem alınabileceğini irdeleyeceğiz...



İlk önce XSS’in ne olduğundan bahsederek başlamak daha uygun olur.

XSS Nedir ?

XSS kısaca, HTML ve JavaScript yardımıyla açığı olan sitelerdeki script kodlarına ekleme yaparak istenilen yönde işlem yapmak demektir.Bunun kötüye kullanım yolu; açığın bulunduğu sitenin kullanıcılarına içerisine istediğimiz işlemi yapan kod parçacığını enjekte edip link halinde vermek.Bu açığa örnek olarak son yılların en büyük sistem açıklarından birisi olan Hotmail’deki XSS açığını verebiliriz.

XSS’in en çok kullanıldığı alan cookie çalma yöntemidir.

Cookie Nedir ?

Cookie : Ana makine’dan istemci makina’ya gönderilen .txt uzantılı bir dosyadır.Bu dosyada sizin ana makine’deki siteye bağlandığınızda sizin kullanıcı adınız, şifreniz, sisteme otomatik giriş yap seçeneğiniz, sisteme son giriş yaptığınız tarih, sisteme giriş yaptığınız andaki saat bilgisi vs. her türlü bilgi yer alabilir.Genellikle üyelik sistemi olan sitelerde cookie’ler içerisinde kullanıcı adı ve şifresi bulunur.Bu cookie bilgileri eğer başka birisinin eline geçerse ve kendi cookie bilgileri ile sizin cookie bilgilerinizi yer değiştirirse açığı olan siteye bağlandığı anda sizin kullanıcı adı ve şifreniz ile sisteme bağlantı sağlanmış olacaktır.Cookie’ler sizin Cookies klasörünüzde tutulur ve her alan adı için ayrı cookie oluşturulur.

XSS saldırılarına karşı kod güvenliğimizi nasıl sağlarız ?

Kullanıcıdan aldığımız bilgiyi direk olarak veritabanımıza kaydediyorsak ve yine aynı şekilde verilerimiz veritabanından kullanıcıya direk olarak gönderilmesini sağlıyorsak; kötü niyetli kodların bizim sistemimizde çalışmasına olanak sağlamış oluruz.

Örnek olarak :

Kullanıcılarımız için bir MemberNetwork tasarladık ve bir kullanıcının diğer bir kullanıcının profiline eklenecek yazılar yazmasına olanak sağladık.MemberNetwork üzerinde kötü niyetli kullanıcının diğer kullanıcının profiline eklenecek yazı kısmına şeklinde bir yazı yazması bu yazının profiline bu yazının eklenmiş olduğu kullanıcının profiline giriş yapıldığı zaman bu kod parçasının olduğu kısım çalışmaya başladığı anda profil kısmında bulunduğumuz site http://www.cyber-security.org adresine yönlenecektir.

Şimdi de yukarıdaki adres yönlendiren kod parçacığımız yerine başka bir kod yazalım.

şeklinde bir kod parçacığı eklediğimizde bu kod çalıştığı anda kullanıcının Session bilgilerini kotuniyetlikullanici.com adresi üzerindeki cookieBilgileriniAl.aspx isimli sayfa’nın cookieBilgi değişkenine atayacaktır ve kötü niyetli kullanıcının sistemine kayıt edecektir.

Aslında ASP.NET programcıları XSS konusunda diğer programcılardan biraz daha şanslı.Çünkü "<" ve ">" işaretleri arasında gelen bilgiler "Potansiyel Tehlikeli Bilgi" olarak algılanır ve genellikle sistemde hataya neden olur.

Mesela programcı sisteminde "FCK Editör" kullanmak istediğinde FCK Editör’ün kullanıldığı sayfanın başına ValidateRequest = false şeklinde bir kod parçası eklemek zorunda kalıyor.Bu durum da XSS saldırıları için ortam oluşturuyor.

Buraya kadar hep HTML üzerinde oluşabilecek açıklardan bahsettik.Bu JavaScript, VBScript ve XML ile olmayacağı anlamına gelmez.

JavaScript için bir örnek kod parçası yazalım :

default.aspx sayfamızda bulunan JavaScript’imiz ;

------------------------------------------------------------------------------------------------



------------------------------------------------------------------------------------------------

default.aspx sayfamızdan gelen bilgi ;

------------------------------------------------------------------------------------------------

LtKullaniciAdi.Text = "Doğukan";

------------------------------------------------------------------------------------------------

Sayfamız çalıştığında ekranda bir uyarı penceresinde "Hoşgeldin Doğukan" şeklinde bir uyarı çıkacaktır.

Şimdi buradaki kullanici adi bilgimizin veritabanımız üzerinden geldiğiniz varsayalım ve kötü niyetli kullanıcı sistemimize üye olurken kullanıcı adı bilgisine " ’location.href= "http://www.cyber-security.org’; alert(’Yönleniyor’); "şeklinde bir ifade girerse bu kod çalıştığı zaman ekranda "Hoşgeldin " yazısı gözükecek ve sistem hemen http://www.cyber-security.org adresine yönlenecektir.

Sayfamız derlendiği zaman oluşacak JavaScript kodunu inceleyelim :

------------------------------------------------------------------------------------------------



------------------------------------------------------------------------------------------------

şekline dönüşecektir ve site yönlenecektir.

Buraya kadar saldırının mantığı ve nasıl gerçekleştiğinden bahsettik.Şimdi de buna karşı nasıl önlemler alacağımıza gelelim.XSS açığını önlemek için "Microsoft Anti-Cross Site Scripting Library" kütüphanesini kullanacağız.

Kütüphaneyi http://www.microsoft.com/downloads/details.aspx?FamilyId=EFB9C819-53FF-4F82-BFAF-E11625130C25&displaylang=en adresinden temin edebilirsiniz.

Kütüphaneyi kurduktan sonra Program Files\\Microsoft\\Anti-Cross Site Scripting Library V1.0\\Library\\ klasörünün içinden kullanıdığınız .NET framework sürümünün bulunduğu klasör içerisindeki AntiXSSLibrary.dll dosyasını projemize referans olarak ekliyoruz.Bu işlem bittikten sonra kütüphaneyi Microsoft.Application.Security.AntiXSS namespace’i üzerinden kullanmaya başlayabiliriz.Kütüphane içerisinde 7 tane statik metod bulunmaktadır.Bunlar;

• HtmlEncode
• HtmlAttributeEncode
• JavaScriptEncode
• UrlEncode
• VisualBasicScriptEncode
• XmlEncode
• XmlAttributeEncode

metodlarıdır.

Az önce verdiğimiz örnek kodun güvenliğini sağlayacak kodu yazalım :

------------------------------------------------------------------------------------------------

using Microsoft.Security.Application.AntiXss;

...

LtKullaniciAdi.Text = JavaScriptEncode(" location.href= "http://www.cyber-security.org’; alert(’Yönleniyor’) ");

------------------------------------------------------------------------------------------------

Kodumuzu bu şekilde derlediğimizde yönlendirme olmayacaktır.

XSS saldırılarından kullanıcı olarak nasıl korunuruz ?




http://www.cyber-warrior.org/Root.asp?Action=Download&Downloadid=254 adresinden indireceğiniz CW XSS Security programı ile güvenliğinizi arttırabilirsiniz.

CW XSS Security sayesinde farkında olmadan tıkladığınız linkteki, gizli-aşikâr frame içinde XSS saldırısı olma ihtimali olan bir kod var ise o kod parçacığı devreye girmeden CW XSS Security eklentisi devreye girerek size bir uyarı mesajı verir.Sizden bu konuda onay ister.Ayrıca onay isterken saldırganın post adresini decode edip size gösterir.Böyleye yeni bir XSS açığı çıktığında bunu kötü niyetli birisi sizin üzerinizde denemeye çalışıyor ise buna yakalanmazsınız ve o sitede bulunan açığı da öğrenmiş olursunuz.

Hiç yorum yok:

 


BilgininAdresi Bilginin Tek Kaynağı

BilgininAdresi Bilginin Tek Kaynağı

BilgininAdresi Bilginin Tek Kaynağı

BilgininAdresi Bilginin Tek Kaynağı

BilgininAdresi Bilginin Tek Kaynağı

BilgininAdresi Bilginin Tek Kaynağı

BilgininAdresi Bilginin Tek Kaynağı

BilgininAdresi Bilginin Tek Kaynağı

BilgininAdresi Bilginin Tek Kaynağı

BilgininAdresi Bilginin Tek Kaynağı

BilgininAdresi SEO Yarışması BilgininAdresi.NET SEO Yarışması Katılımcısı

="BilgininAdresi SEO Yarismasi"" href= " http://www.bilgininadresi.net">BilgininAdresi.NET SEO Yarismasi Katilimcisi