Sunucu Güvenliği : SQL Injection

Adı üzerinde SQL enjeksiyonu. Kelime bence tam olarak oturmuyor ama konuyu terimsellestirmek için yazılmış. Sanki SQL’e bir virüs enjekte ediliyor gibi bir anlam çıkartıyor insan ilk duyduğunda. Oysa tam olarak SQL’e SQL enjekte edilerek yapılıyor bu saldırı.

Diyelim ki bir kullanıcı giriş formunuz var. Bu formda haliyle kullanıcı adı, şifre ve CSRF ataklarini onlemek için kullandığınız captcha değerini alıyorsunuz. Hatta SSL güveliği tam olarak kapsıyor sitenizi ve XSS saldırılarından korunmak ile ilgili tüm tedbirleri de aldınız. Fakat hala acemice/dikkatsizce yazılmış bir kodunuz varsa veya çok eski bir php4 ya da php5 kodu çalıştırıyorsanız bir açığınız olabilir. SQL kodlarının bir enjeksiyon denemesi ile tamamlanarak veritabanı sorgularınızın bozulup bozulamayacağını bilmiyorsunuz. Örnek verirsek;

gibi bir formunuz var diyelim. Normalde bu kisimdaki beklentiniz kullanici adi kismina kullanici adi ya da eposta yazilmasi. Sizin de bunu PHP gelistiricilerinin coktandir tavsiye etmedigi ama hala pek cok eski kitapta yer alan mysql_* fonksiyonlari ile kontrol ettiginizi dusunelim. Basitlestirince soyle bir sorgunuz var demek oluyor;

Bu sorgu yaptigi kontrolde username alani yerine peki bu kod gelirse ne olacak;

Sorgumuz bu durumda kullanici adi bos veya 1=1 ise anlamina geldi. Bu şekilde saldırgan sadece bu alanı değil aynı zamanda captcha ya da parola alanlarını da kullanabilir. Yani tüm sorguyu istediği hale getirebilir. PHP geliştiricileri bu noktada önceden kendi classlarini kullanarak tek tırnak veya çift tırnak gibi karakterleri regex filtreleri ile temizliyorlardı. Addslashess, mysql_real_escape_string gibi bazı fonksiyonlar kullanılıyordu. Fakat bu yeni PHP versiyonlarında mysql driverlerin yerini mysqli ve PDO aldığı zaman değişti.

Örneğin bir PDO baglantısında dışardan aldığınız verileri için sorgunuzu şu şekilde hazirladığınızda SQL injection riskiniz ortadan kalkıyor.

Ayni şekilde ( ben bu noktada PDO kullanmanizi tavsiye ettigim icin mysqli sorgusunu sona koyuyorum ) mysqli için de bunun bir yolu var.

Bu noktada güvenliğin bir maliyeti oldugunu da söylemek gerek. Mysqli performansi %1-5 arası sorguya gore mysql_* ile karsılaştırıldığında düşebiliyor. Fakat zaten mysql_* için yazılacak veya kullanılacak kodların da performansa etkisi olacağı için bunu görmezden gelebiliriz.

Bu yazıda SQL Injection ile ilgili örnekler vermiş oldum. Bunu kendi kodunuza uyarlayarak güvenliği arttırabilirsiniz. Zaten artık mysql_* yeni PHP sürümlerinde kullanılmayacak. Fakat injection mantığını öğrenmek, özellikle kullanıcıdan gelen veriye güvenmemek refleksinizi korumalısınız.

Herkese iyi çalışmalar…

Guncelleme (15 Ekim 2017):

Bir de SQL Injection icin sunucu ayarlari kapsaminda alinabilecek bir tedbir var. Apache modullerinden security modulu ile SQL Injection aciklarinin onune gecilebiliyor. Bunun icin modulu sonradan kurmaniz gerekiyor cunku default kurulumda gelmiyor. Ayrica bu konu icin bir yazi yazacagim.

Sunucu Güvenliği : SSL – Secure Sockets Layer

Zamanında özellikle banka poslarini kullandığım websitelerinde başımı bir hayli ağrıtmıştı SSL işleri. O zamanlar bankalar ( şimdi öyle mi bilmiyorum ) özellikler kredi kartı bilgilerinin alındığı sayfada kullanmanızı istiyorlar, sitenin geneli yerine sadece bu sayfayı kontrol ediyorlardı. Tabi bu kontrol o browserda aşağıdaki resmi görmekten ibaretti diye düşünüyorum.

ssl

Browser adres kısmında o sayfanın o sayfada SSL kullanıldığını ve kullanılmakla kalmayıp SSL’in sağlıklı çalıştığını bu şekilde anlıyoruz. Peki özellikle alışveriş sitelerinde gördüğümüz ve nihayetinde artık Google tarafindan tüm sitelerin kullanmasını tavsiye ettiği bu SSL nedir ?

SSL siteniz ile kullanıcılar arasındaki veri alışverişini sifreleyerek dışardan erişimler olursa bu verinin okunmasına engel olmak için kullanılan bir standart. Bu biraz yaptığı ise göre SSL için aslında süslü bir cümle. Çünkü SSL sadece bunu yapıyor. Siteniz için bunun da ötesinde bir güvenlik sağlamıyor. Hala XSS veya CSRF aciklariniz sitenizde olabilir. Hala acik olmamasi gereken portlariniz ornegin UFW gibi bir firewall ile kontrol edilmiyor olabilir.

Peki SSL ubuntu temelli bir sunucu da apache2 bir websitesine nasil kuruluyor?

Bunun için eskiden ( 2007-2008 yıllarından söz ediyorum ) SSL sertifikası sağlayan bir firma bulup, sitenize ait bilgileri bu siteye girerek belirli bir ücret karşılığında sertifika dosyalarını alıyordunuz. Sonra da shared bir hosting ise Cpanel veya plesk kısmından dosya ve bilgileri girerek SSL’i aktif ediyordunuz. Para vermenizin nedeni browserlarin bu ücretli SSL sertifikalarını ( özellikle IE ) tanıması gerekmesiydi. Diğer türlü “tam da güvenemediğim bir SSL sertifikası var ama girmek ister misin bu siteye” tadında bir uyarı görüyordu ziyaretçi. Bu da güvenli göstermeye çalıştığınız siteyi tam tersi kullanıcıya durduk yere sanki güvensiz gibi gösteriyordu.

Şimdi işler biraz daha ucuz ( aslında artık bedava ) ve kolay. Chrome vb. yaygın browserlar ücretsiz verilen sertifikaları da tanıyor. Benim tavsiye edeceğim ( ömrü uzun olsun ) Certbot  sitesidir.

Certbot seçtiğiniz sunucu yazılımı ve işletim sistemini seçtikten sonra sizi bir kurulum ekranına yönlendiriyor. Bu ekranda sisteme nasıl kuracaginiza dair talimatları bulabilirsiniz. Bayağı basit bir kurulumu var ubuntu sistemler için. Ben de zaten apache2 ve ubuntu 16.04 LTS ile denedim. Gayet memnun kaldım. Çünkü sizde sertifika kurulumu yaparken göreceksiniz ki apache virtualhost dosyalarına bile müdehale edip sertifika satırlarını iliskilendirmesini yapıyor bu terminal uygulaması.

Bu noktada WordPress içine SSL kuracağım nasıl yapacağım diyenler shared hostinglerinde ssh erişimi olmadığı için uzuleceklerdir. fakat hepsini biraz linux öğrenip kendi vpslerini örneğin digitalocean üzerinde açarak pratik yapmaya davet edebiliriz. aylık 5 dolar ile eskiden çok daha pahalıya patlayacak tecrübeyi edinebilirsiniz. Gerçi sadece blog yazıyorsanız bana göre google blog servisini kullanın çok daha iyi.

Kurulumu talimatları izleyip yaptığınızı ve kurulum sırasında sorulan redirect opsiyonu ile https olmayan adreslerinizi yonlendirdiginizi varsayiyorum. Peki el emeği göz nuru yaptığınız sitede hala çalışmıyorsa SSL neden ? Büyük ihtimalle yazdığınız kod içerisinde https olmayan medya ( image, object, video  …) dosyalari cagriyor olmanizdan. Evet SSL veri transferinin tamamini sifreleyerek browsera gondermek istedigi icin sizde bu medya cagrilarini http degil https ile cagirmalisiniz. O zaman sorununuz çözülecektir. WordPress gibi hazır yazilimlarda ve symfony, laravel gibi iyi frameworklerde ( kurallara uyduysaniz ) bunu yapmak çok basit zaten. Bir stackoverflow aramasina bakar.

Bu yazıda SSL’in nasıl çalıştığına ve nasıl vps, dedicated sunucunuza kurabileceginize değindim. Fakat unutmayın ki SSL demek güvenliğin tamamını sağladınız demek değil. Sunucu güvenliği ile ilgili diğer yazılarıma da mutlaka bakın.

Bir de her SSL ile ilgili türkçesini bulamadığım su haber ile ilgili sizi haberdar etmis olayim. Zira CloudFlare DDos forumlarda ataklarindan korunmak için ve pratik SSL kullanmak için pek övülmekte.

Herkese iyi çalışmalar…

Sunucu Güvenliği : UFW – Uncomplicated firewall

Sunucu güvenliği konusunda portlar önemli. Zira sisteme veri alışverişinin büyük bir bölümünü portlar aracılığı ile yapıyor. Peki portları nasıl kontrol edeceğiz ve izinlerini nasıl düzenleyeceğiz ?

Linux için aslında bu büyük bir problem değil. Çünkü kurulduğu zaman tüm dışarı çıkışlar serbest, tüm içeri girişler kapalı şekilde kuruluyor. Linuxun bu işi yaptığı ana enstrümanı da yine kendisinin bir parçası IP Tables. IP tables linux çekirdeğinin etkileşimini modifiye edilebilen çeşitli kurallarla düzenliyor. Bunu da tabi ki IPv4 ve IPv6 için yapabiliyor.

Fakat IP tables sistemci değilseniz kullanması o kadar da kolay bir yapı değil. Bence bir yazılım geliştirici ve sistemcinin ayrılmaya başladığı noktalardan birisi IP Tables olabilir. Linux çekirdeği ve etrafındaki yapılar bence tam olarak sistemci işleri. Peki yazılım geliştiriciler için sistemci olmadan yapabilecekleri bir şeyler yok mu?

Linux kapsamında bildiğim en iyi cevap UFW. Açılımı Uncomplicated Firewall yani karışık olmayan ateş duvarı. Bu basit firewall tabi ki her zaman desteklediğim üzere bir terminal aracı. GUI ile kullanılıp kullanılmadığını bilmiyorum. Terminal içinde çalışmayan guilerden de uzak durmanızı tavsiye ediyorum. Unutmayın ki her grafik arayüz sizinle verinin arasına girecek başka bir yanıltıcı unsur, başka bir sistem yükü olacak. Bu sebeble komut yazmaktan korkmayın, bir gün arayüzlerle uğraşmaktan daha hızlı olacağını göreceksiniz.

Öğüt kısmını tamamladığıma göre gelelim UFW nasıl kullanılıyor kısmına. Ubuntu server kullanıcıları için şöyle başlayalım.

Kurulumdan hemen sonra başınız ağrıdığında yardımcı olsun diye reset atmayı görelim. Öğrenmek için yaptıklarınızı resetlemeniz kolay olsun.

UFW’yi aktif hale getirmek için;

diyoruz. Haliyle durdurmak için de dışable kullanılıyor.

Gelen ve giden trafikleri de toptan kontrol etmek mümkün. Fakat bunu yaparken sunucunuza kurduğunuz SSH bağlantısı üzerinde yapmadığınıza emin olun derim. Sonra bağlantınız koparsa tekrar kapattığınız portlara erişemezsiniz. Kendi bilgisayarınızda denemek daha iyi bir fikir.

ya da engellemek için allow yerine deny kullanıyorsunuz. Bu komutları bence hiç kullanmayın. Toptan bir iş neredeyse hiç yapılmamalı. Çünkü genellikle linuxda toplu uygulamaları geriye döndürmek zordur. Kazara toptan chmod değiştirmek gibi.

Tüm portları kapalı varsaydığımız için önce web sunucumuzun ( apaçhe veya nginx gibi ) ve ssh erişimizin erişime açıldığına emin olalım.

FTP de aynı şekilde açılabiliyor. Fakat ben FTP de kullanmanızı tavsiye etmiyorum. Bunun yerine scp ve rsynç komutlarını bir başka blogda anlatacağım.

Peki işler bu kadar basit mi? Hemen bitti mi ? Tabi ki hayır. Bu noktada biraz daha derine inelim. Örneğin SSH portumuzu sunucumuzu olası bir saldırıdan korumak için değiştirdiysek ne olacak ? Tabi ki bu komut çalışmıyor. UFW, SSH için yazılmış confiğe girip portu okuyarak bu işi yapmıyor. Default portu yani 22 nolu portu kullanıyor. Port açmak komut basit tabi.

bu şekilde 22 nolu portumuzu erişime açtık. İyi güzel de bu portlara kuralları tanımlayınca sonra nasıl göreceğiz ?

Karşınıza düzenlediği kuralları çıkartacaktır. Tabi sadece ufw statüs de çalışır ama numaralı listeme yaparsak kuralı numara ile silmemiz kolay olacaktır. Kural silmek demişken;

3 nolu tanımımızı sildik. Kuralları toptan silmek için reset atmanız gerektiğini söylemiştim.

Port ayalarında değişiklikler yaptıktan sonra UFW’yi reload etmeyi unutmayın.

UFW hakkında yeni tecrübe ve bilgiler edinirsem yine bu blog kapsamında paylaşacağım. Herkese iyi çalışmalar.