Kod Erişim Güvenliği

Kod Erişim Güvenliği

Birçok güvenlik sistemi kullanıcıların kimliklerine göre sisteme ve kaynaklara erişim haklarını verir ve/veya kısıtlar. Kullanıcı kimliği olarak çoğu zaman kullanıcı adı ve şifre kullanılmaktadır. Bu yazımızda .NET"in sağladığı kod bazındaki güvenlik katmanlarının temel olarak yapısını inceleyeceğiz.

Kullanıcılar kullandıkları kodların kaynaklarını bilmemektedirler, dolayısıyla kullanılan programın sadece vaat ettiği işi yaptığını veya yapmadığını bilmeleri de olanaksızdır. Daha önceki yazılarımızda da sıkça bahsettiğimiz trojan ve trap doorlar da tamamiyle bu mantık üzerine çalışmaktadırlar. Bu yüzden çoğu işletim sistemi kodu çalıştırmadan önce kodun güvenilir bir kaynaktan gelip gelmediğini araştırır. Örneğin web sitelerindeki ActiveX kontrollerinin çalıştırılabilmesi için kullanıcının siteye güvendiğini belirtmesi gerekmektedir. Buna karşın, internet üzerinden dağıtılan, güvenilir olduğuna inandığınız bir programın gerçekten de o program olup olmadığının da teyidi gerekmektedir. Bir zamanların en iyi virüs tarama programı olan FProt programındaki küçük bir hata bir çok sistemin zarar görmesine sebep olmuştur. Bu tarihteki FProt programının sürümünde unutulmuş, çok önemli bir detay vardı: Fprot tüm sistemde virüs taraması yaparken sadece kendisini tarayamıyordu. İnternet üzerinden dağıtılan virüslü FProt programını kuran kişilerin bilgisayarlarında yapacakları ilk virüs taramasıyla bilgisayarlarındaki tüm dosyalara virüs yayılması bir oluyordu. Virüs, FProt programıyla henüz taranan dosyaya kendi bulaştırarak yayılıyordu. Virüsün kaynağı virüs tarama programının kendisi olunca temizlenmesi de imkansız bir hale geliyordu. Zaten FProt programındaki bu hatadan sonra FProt"a olan güven fazlasıyla sarsılmıştır.  Kod erişim güvenliği, işlemleri ve kaynakları korumakla yükümlü koda erişimleri kontrol eden güvenlik mekanizmasıdır. Biraz karışık bir tanım gibi gözükse de temelde yapılan işler oldukça basittir. .NET Framework"teki kod erişim güvenliği temel olarak aşağıdaki işlemleri yapar:

Çeşitli sistem kaynaklarına erişim haklarını tanımlar. Yöneticilerin güvenlik politikalarını belirli bir grup kod için özelliştirmeleri için gerekli ilişkilendirmeleri yapmalarını sağlar. Bir kodun çalışabilmesi için gerekli olan izin ve izin kümelerinin neler olması gerektiğini, sahip olması ve sahip olmaması gereken izinlerin neler olduğunu tanımlanmasını sağlar. Belleğe yüklenen her bir assembly için izin ve ayrıcalıkları verir. Ve kodu çağıran kişilerin yaptıkları her işleme göre nasıl bir güvenlik politikası izleneceğini belirtir. Kodu çağıran kişilerin (ya da programların) belirli ayrıcalıklara sahip olmasını sağlar. Kodu çağıran kişilerin digital imzalarının kontrolünün yapılabilmesini sağlar. Bu da kodun sadece belirli bir grup, kurum/ kuruluş tarafından çağrılabilmesini sağlar. Kodu çağıran program parçaçıklarının call stack"te sahip olmaları gereken hak ve ayrıcalıklar için gerekli kısıtlamalara zorlar.

Bir kodun belirli bir işlemi gerçekleştirmeye ya da belirli bir kaynağa erişimi için yeterli haklara sahip olup olmadığının tespiti için "call stack" (çağırma yığıtı) kullanılır. Her fonksiyon içerisinde çağırdığı fonksiyonu çağırırken "call stack" adını verdiğimizi yığıta gerekli atamaları yapar. Bu atamalar, çalışan fonksiyona çağırdığı fonksiyondan döndüğünde, her şeyi bıraktığı gibi bulması için sistem tarafından otomatik yapılır. Assembly ile uğraşmış olalnlar bilirler. Bir fonksiyonu çağırmadan önce tüm flagları, registerları stack"e push ederler. Fonksiyon dönüşü aynı değerleri tekrar pop ederler. "Call Stack" bu yapıya benzer bir yapıya sahiptir, bu yapı "call stack" değildir. Yine COM programlama ile uğraşanlar bilecektir, "Call Context" fonksiyonlara parametre geçirmeden değişken ve/ve ya değer göndermenize izin veren yapıdır. .NET destekli çoğu web sitesi sisteme giriş yapmış kullanıcı adını session"da ya da cookie"de tutmak yerine, call contextte tutarak sistemlerinin güvenliğini en iyi düzeye getirmeye uğarşırlar. Bu uğraş oldukça yerinde ve doğru bir uğraştır. Bu sayede sisteminizde bu ya da benzer sebepten oluşabilecek güvenlik açıklarını önleme görevini COM, COM+ ya da .NET"e yüklersiniz. COM, COM+ ya da .NET dedik çünkü call context bu üç yapıyla da birebir uyumludur. Şimdi .NET"in bu güvenliği nasıl sağladığına kaldığımız yerden devam edelim. Her fonksiyon kendisini çağıran diğer fonksiyonları sahip olması gereken gerekli güvenlik izinlerinin ya da ayrıcalıklarının olup olmadığının kontrolünü yapar. Bu kontrol sırasında her hangi bir güvenlik ihlaliyle karşılaşılırsa, security exception atılır ve erişim engellenir. Bu kontrol işlemine stack walk adı verilir. Stack walk .NET"de daha az güvenilen kodun daha çok güvenilen bir kod ile çağrılması ve izin verilmeyen işlemler gerçeklenmesini engelleyecek şekilde tasarlanmıştır. Yani bu demektir ki, FProt programının virüslü versiyonu .NET teknolojilerini kullanılarak gerçeklenmiş olsaydı, bu tür bir güvenlik açığının oluşması imkansız olurdu. Kod erişim güvenliğinin nerede kullanılabileceğini düşünelim. Kullanıcının belirli bir bilgiyi girebilmesi bir Web sitesinden bir kontrolü indiren bir uygulamayı ele alalım. Bu kontrolde istemci tarafında kurulu olan bir kütüphaneyi kullanarak oluşturulmuştur. Bunun için sağlanabilecek kod erişim güvenliği senaryoları aşağıdak gibi olabilir.

Yüklemeden önce, sistem yöneticisi bir digital imza kullanarak, gerekli ayrıcalıklara sahip olacak kodun güvenlik politikasını belirleyecek şekilde sistemi tasarlayabilir.  Kullanıcının önceden belirlenmiş Internet ayarlarının tümü zaten bizim uygulamamız için de geçerli olacaktır. Yapılacak diğer ek işler için uygulama inen kontrolün geçerlilik testi için digital imza kullanır. İnen kontrol de kendisini kullanacak kod için aynı digital imza kontrolünü yapabilir. Yani ActiveX gibi çalışır. ActiveX"i yükleyebilmek ya da kullanabilmek için kullanıcının kendisine yöneltilen güvenlik kontrolü sorusuna olumlu cevap vermesi gerekmektedir. Yükleme zamanında, kontrol güvenli bir imzaya sahip olmadan, yürütme süresince Internet güvenlik ayarlarının da hepsi iptal olur. Bu sayede güvenliği tamamen sizin kontrolünüze alırsınız. Bir önceki senaryo ile arasındaki en önemli fark, sistem güvenliği için Internet ayarlarında önceden tanımlanmış izin ve ayrıcalıklara ek yapıyorduk. Ancak artık o hakları da kontrolden ve kullanıcıdan almış oluyoruz. Ve diğer önemli fark da güvenlik kontrollerinin yükleme zamanında yapılmasıdır. Bir başka senaryo ya da yaklaşımda şöyle olabilir. Kullanıcının bilgisayarında normal sahip olduğu hakların üzerinde bir işlem gerçekleneceğinde güvenlik kontrolü yani "stack walk" işlemi gerçeklenebilir. Diğer güvenlik senaryolarından en önemli farkı, güvenlik kontrollerinin diğerlerinde yükleme işleminden önce ya da yükleme işlemi sırasında yapılmasıdır. Bu senaryoda ise bu kontroller gerektiğinde yani ek güvenlik kontrolü gerektiğinde yapılmasıdır.

.NET ile geliştirilen CLR (Common Language Runtime) kullanmayı amaçlayan tüm uygulamalar, yürütme sürecindeki güvenlik sistemi ile ortak çalışmaktadır. Şimdi bu kavramı biraz daha açalım. Geliştirilen uygulamanın sahip olacağı tüm ayrıcalık ve haklar, o an ki uygulamayı çalıştıran kullanıcının grubuna ve sistemin çalışma seviyesine bağlıdır. Çalışma seviyenize göre gerektiğinde donanımın belirli özelliklerinin kullanabilirsiniz. Akıllarda kalabilecek en basit örnek Windows"u güvenli kip de açtığınızda yönetici olarak sisteme girseniz bile, donanımlarınızın tüm özelliklerini kullanamazsınız. Kullanıcı grubuna göre sahip olduğunuz izinler değişir dediydik. Buna verilebilecek örnek ise, şu an giriş yaptığınız sitedir. Sahip olduğunuz kullanıcı adı ve şifreyle yalnızca sitedeki makaleleri okuyabilirsiniz. Yönetici ayrıcalıklarına sahip bir kullanıcı ile giriş yaptığınızda aynı makaleleri değiştirebilirsiniz, ya da yenilerini girebilirsiniz. Çalıştırılan uygulamada aynı şekilde güvenlik ayrıcalıklarını almaktadır. Öncelikle, CLR"den uygulamanın sahip olacağı hak ve ayrıcalıkları alır ve CLR üzerinde çalışmaya başlar. Uygulamanın sahip olduğu hak ve ayrıcalıklar CLR tarafından uygulamanın "call stack" "ine yazılır. Şimdi bu noktada sistemde bir açık olduğu düşüncesine kapılabilirsiniz. "Ben bu uygulamanın call stackindeki ayrıcalıklara sistem yöneticisi ayrıcalıklarını da eklersem, sistem yöneticisi olmadan sistem yöneticisi statüsüne erişebilir miyim?". Eminim bu soru bir çoğunuzun aklına gelmiştir. Cevap tabi ki de "HAYIR !!!!". Sistem yöneticisi olarak erişmek istediğiniz sahip olmanız gereken hak ve ayrıcalıklar "call stack" te yukarıdan aşağıya doğru kontrol edilir. Belki üst katmanları geçmenin bir yolunu bulabilirsiniz. Ancak daha sonraki katmanlarda yani güvenlik kontrolü .NET Framework"e kadar indiğinde, sistem tarafından security exception otomatik olarak atılacak, ve istek red edilecektir.

Ayrıca unutmamanız gereken bir diğer önemli nokta da sistemin geliştirilen bir uygulamanın compile edilme süresince çok zayıf olacağıdır. Her hangi bir şekilde geliştirilen uygulamanın compile edildiği threadin kontrolü kaybolursa, sistemin güvenlik katmanı diye bir şey kalmayacaktır. Geliştirilen tüm işletim sistemlerinde genelde performans nedenleriyle güvenlik kernelde sağlanmaz. Sistem güvenliği işletim sistemleri için birer servistir. Compile süresince compile işlemini gerçekleyen thread kernele erişir. Kernele erişimlerin gerçeklendiği bu anlarda, sisteminiz bu thread üzerinden her türlü saldırıya açıktır. Bunun için gerçekten güvenilir compilerları kullanmanızı öneririz.

Kod erişim güvenliği sağlanmamış uygulamalar hem kullanıcıları hem de uygulama geliştiricileri tehlikeye sokmaktadır. Oluşturacağınız sistem ne denli büyük ve kompleks olursa olsun, .NET gibi güvenilir bir framework üzerine uygulamanızı kurmanız yararınıza olacaktır. .NET ile 3D flight simulator yapılabildiğini de düşünürseniz eğer, geliştireceğiniz uygulamalar için daha güvenilir bir framework bulamazsınız. Kullanacağınız frameworkün ve compiler"in önemini de hatırlattıktan sonra yazımızı tamamlamak istiyoruz.

Son Söz

.NET ile kod erişim güvenliğinin nasıl sağlanacağını incelediğimiz bu yazımız da "call stack" kullanımından bahsettik. Bu tür bir stack walk kullanmak sistemimizin güvenliği için bize oldukça fazla artı getirse de sürekli yapılan bu security checkler sistemimizin performansından götürmektedir. Optimizasyon için stack walk performans için mümkün olduğunca kısa ama güvenlik için de mümkün oldukça uzun olmasına dikkat etmelisiniz. Sistem güvenliği sağlamanın yolu, sistemi ve sistem programlamayı çok iyi bilmekten geçmektedir. .NET ile kuracağınız güvenlik sistemi konusunda bazı senaryolardan bahsettik, bu senaryoları arttırmak tabi ki de mümkün. Yalnız unutmamanız gereken en önemli şey, doğru programlama araçlarını ancak doğru şekilde kullanarak yeterince güvenli sistemleri oluşturabilirsiniz.

Suphi UÇAR – Yunus Emre ALPÖZEN

Döküman Arama

Başlık :

Kapat