Geliştirdiğim websitelerden bir tanesine üç tane hacker arkadaşın saldırmasından sonra güvenliğe gereken önem vermeye başladım. Tam olarak ne zaman güvenliğin üzerine ciddi olarak eğilmeye başladığımı hatırlamıyorum fakat öğrendiğim bazı şeylerin olgunlaştığını düşündüm ve günlüğüme birşeyler karalamak istedim. Bu yazım SQL Injection'dan korunmak için yapılması gerekenlerinlerin başlıklarından ve ipuçlarından oluşacak. Vereceğim bilgiler güvenilir kaynakların taranması sonucu olgunlaşan veriler. Eğer SQL Injection üzerine detaylı bir araştırma yaparsanız benim ulaştığım önemli noktalara ulaşabilirsiniz. Yazımda yararlandığım kaynaklar:
- Hacking Exposed Web 2.0: Web 2.0 Security Secrets and Solutions (ISBN: 978-0-07-149461-8)
- MSDN
- http://asp.net
SQL Injection nasıl yapılır?
Veritabanında yaptığınız insert, update, delete gibi komutlara kullanıcı girdisinin müdehale etmesiyle gerçekleşir. Müdehale etmesi derken, saldırıyı yapan kişi veritabanı üzerinde yönetici olarak yapılabilecek bütün işlemleri gerçekleştirebilir. Hatta veritabanını silebilir... SQL Injection' nın verebileceği zararları anlatan onlarca kaynak var. Bu yüzden ben bu kaynakların araştırılması sonucu derlenmiş çözüm başlıklarını vereceğim. Bahseceğim çözüm önerilerini araştırdığınızda yapmanız gerekenleri öğreneceksiniz. Ama araştırmadan önce de bir klavuza ihtiyacınız var. İşte çözüm yolları:
1. Querystring Verilerini Kontrol Ettirin
Kullanıcılar sayfalar arasında veri transferi için kullandığınız querystring değerlerini görebilirler. Bunun için bu verileri kontrol ettirmeden SQL komutlarınızın içinde kullanmamanız gerekir. Örnek vermek gerekirse: bir tablonuzdan ID değerini baz alarak "ad" diye bir veri çektireceksiniz. Tablonuzu oluştururken ID değerini integer olarak tanımladınız. ID'nin bir integer mı yoksa tipik bir sql injection cümleciği olan ' OR 1=1 -- mi olduğunu kontrol ettirmeniz gerekir. Bu örnek için ID' nin bir integer mı yoksa string mi olduğunu kontrol ettirebilirsiniz. Böylece string veri türünde kullanıcı querystring'e değer atadığında kodunuz hata verecektir.
Bu verdiğim örnek sadece bir senaryo için geçerli. Güvenlik söz konusu olduğu zaman bütün ihtimalleri göz önünde bulundurarak önem alın ve asla kullanıcı girdilerine güvenmeyin! Querystring'lerden gelen saldırıları önlemek için "sql injection querystring" anahtar kelimeleri ile google da arattığınız zaman bahsettiğim korunma yöntemi ile ilgili bilgiye sahip olacağınızı düşünüyorum.
2. Parametreler Kullanın
Yukarıda verdiğim ID örneğinden gidersek anlatacağım husus daha iyi anlaşılır. C# kullanarak iki türli sql komutu yazabilirsiz:
Birinci örnek: "SELECT * FROM tablo_test WHERE ID='" + ID + "'";
İkinci örnek: "SELECT * FROM tablo_test WHERE ID=@ID";
Bu ikinci örnekte @ID diyerek ID' nin değerinin bir parametreye atıyorsunuz. Bunun yapmak ne işinize yarayacak? Eğer birinci örnekteki gibi yaparsanız kullanıcı girdisi olan ID değeri direk olarak SQL komutuna dahil olacaktır. Eğer kullanıcı biraz art niyetli biriyse ve ID değerine ' OR 1=1 gibi şeyler yazarsa bütün kayıtları görebilecektir. Eğer bu SQL komutu bir login kontrolü için yapılıyorsa bunu yazan kişi sisteme giriş yapabilecektir.
Bunu engellemek için ikinci örnekteki gibi parametre kullanmalıyız. Böylece ASP.NET' e şunu söylemiş oluyoruz: Kullanıcıdan gelen değer sadece parametre değeridir, bir SQL komutu değildir. Böylece ASP.NET sayfamızda buna göre davranarak hata verecektir.
Anlattığım hususun kodlarını ve gerçek uygulamasını görmek için "sql injection sql parameter" anahtar kelimelerini aramanız için öneririm.
3. Hata Mesajlarını Gizleyin
Saldırı yapanlar genellikle sisteme hata verdirerek veritabanı bilgilerini öğrenmeyi hedeflerler. Eğer sistemin verdiği hataları cömertçe kullanıcılara gösteriyorsanız ASP.NET sayfanız saldıranlara eğitim içerikli hatalar verecektir. Bu verilen hatalar içerisinde tablo ve field isimleri geçtiği zamanda saldıran kişinin yapması gereken şey doğru SQL komutu ile saldıyı yapmak. Bunun olmasını engellemek için web.config dosyasındaki customErrors tag'ı aşağıdaki gibi olmalıdır:
<customErros mode="On" defaultRedirect="Hata.aspx" />
Böylece sistem bir hata verdiği zaman kullanıcıya eğitici ve açık verici hata sayfaları yerine Hata.aspx sayfasını göstermiş olacaksınız.
Detaylı bilgi için "sql injection customErrors" anahtar kelimelerini öneririm.
4. Şüpheli Karakterleri Temizleyin
SQL komutlarınıza müdehale ederek veritabanınıza zarar verebilecek komutları engellemek için şüpheli karakterleri temizlemeniz gerekir. Bazı şüpheli karakterler:
"\"", "\\", "/", "*", "'", "=", "-", "#", ";", "<", ">", "+", "%"
Özellikle querysting değerlerinde bu temizlemeyi yapmanızı öneririm. Fakat belirttiğim gibi kullanıcı tarafından gelen bütün girdiler için yukarıda bahsettiğim önlemleri almanız gerekmektedir.
Sonuç
Eğer web üzerine uzmanlaşmak istiyorsanız bu söylediğim önerilere kulak vermenizi öneririm. Kullanıcılara yaptığınız uygulamaları açmadan önce sql injection saldırılarına karşı bu önlemleri almazsanız ileride telafisi olmayan sonuçlarla karşılaşabilirsiniz. Bu yazımda sql injection saldırılarına karşı alınabilecek önlemlerin ipuçlarını vermeye çalıştım. Umarım sql injection önlemlerini öğrenirken bu yazı sizlere yol gösterici olur. Başka bir güvenlik yazısında buluşmak üzere...