26 Haziran 2009XSS Filter Fonksiyonu
Bir çoğumuz uygulama yazmaktayız veya bir şekilde kullanıcılardan veri almaktayız. Herşeyi yapıp bitirdiğimizde ise oh be çekemiyoruz ne yazık ki
bir de bunun kötü niyetli kişiler olduğunu düşünüp sisteme zarar verecek halleri düşünüp kestirip önüne geçebilmek gerekiyor. Genelde sitelerimize kullanıcının veri girebileceği yerlerden sızmaya çalışılır hoş bazen bir ID alanından da sql injecktion yapılabiliniyor ama ben bu konuda XSS olayına kısaca gireceğim.
XSS açıkları genelde programcının gelen verileri süzmeden veritabanına eklemesi ve listelenmesi olayıyla ya da alınan bir değişken değerin filtrelenmeden ekrana yazdırılmasıyla olmakta. Bu sebeple istenmeyen durumlara sebebiyet vermekte nedir bu sebepler dersek eğer en basitinden yönetici bilgileri çalınabilir eğer cookie bir oturum kullanıyor ise tabiki normal session ise pek bir işe yaramayabilir..
Kısa bir RemoveXSS fonksiyonunu tanıtacağım zira kendiside çok basit ve etkili bir fonksiyon ve bir çok xss den kurtulmanıza olanak sağlıyor.
function RemoveXSS($val) { $val = preg_replace('/([\x00-\x08,\x0b-\x0c,\x0e-\x19])/', '', $val); $search = 'abcdefghijklmnopqrstuvwxyz'; $search .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; $search .= '1234567890!@#$%^&*()'; $search .= '~`";:?+/={}[]-_|\'\\'; for ($i = 0; $i < strlen($search); $i++) { $val = preg_replace('/(&#[xX]0{0,8}'.dechex(ord($search[$i])).';?)/i', $search[$i], $val); // with a ; $val = preg_replace('/(�{0,8}'.ord($search[$i]).';?)/', $search[$i], $val); // with a ; } $ra1 = Array('javascript', 'vbscript', 'expression', 'applet', 'meta', 'xml', 'blink', 'link', 'style', 'script', 'embed', 'object', 'iframe', 'frame', 'frameset', 'ilayer', 'layer', 'bgsound', 'title', 'base'); $ra2 = Array('onabort', 'onactivate', 'onafterprint', 'onafterupdate', 'onbeforeactivate', 'onbeforecopy', 'onbeforecut', 'onbeforedeactivate', 'onbeforeeditfocus', 'onbeforepaste', 'onbeforeprint', 'onbeforeunload', 'onbeforeupdate', 'onblur', 'onbounce', 'oncellchange', 'onchange', 'onclick', 'oncontextmenu', 'oncontrolselect', 'oncopy', 'oncut', 'ondataavailable', 'ondatasetchanged', 'ondatasetcomplete', 'ondblclick', 'ondeactivate', 'ondrag', 'ondragend', 'ondragenter', 'ondragleave', 'ondragover', 'ondragstart', 'ondrop', 'onerror', 'onerrorupdate', 'onfilterchange', 'onfinish', 'onfocus', 'onfocusin', 'onfocusout', 'onhelp', 'onkeydown', 'onkeypress', 'onkeyup', 'onlayoutcomplete', 'onload', 'onlosecapture', 'onmousedown', 'onmouseenter', 'onmouseleave', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onmousewheel', 'onmove', 'onmoveend', 'onmovestart', 'onpaste', 'onpropertychange', 'onreadystatechange', 'onreset', 'onresize', 'onresizeend', 'onresizestart', 'onrowenter', 'onrowexit', 'onrowsdelete', 'onrowsinserted', 'onscroll', 'onselect', 'onselectionchange', 'onselectstart', 'onstart', 'onstop', 'onsubmit', 'onunload'); $ra = array_merge($ra1, $ra2); $found = true; while ($found == true) { $val_before = $val; for ($i = 0; $i < sizeof($ra); $i++) { $pattern = '/'; for ($j = 0; $j < strlen($ra[$i]); $j++) { if ($j > 0) { $pattern .= '('; $pattern .= '(&#[xX]0{0,8}([9ab]);)'; $pattern .= '|'; $pattern .= '|(�{0,8}([9|10|13]);)'; $pattern .= ')*'; } $pattern .= $ra[$i][$j]; } $pattern .= '/i'; $replacement = substr($ra[$i], 0, 2).'<x>'.substr($ra[$i], 2); $val = preg_replace($pattern, $replacement, $val); if ($val_before == $val) { $found = false; } } } return $val; }
Evet üstteki fonksiyonumuz ile kullanıcılardan alınan verileri geçirdiğimizde gönül rahatlığıyla verileri ekleyebilir veya listeleyebiliriz.
Kullanımına bir örnek vererek yazımızı noktalaylım.
$veri = ' Ali Veli Deli <img src="javascript:alert(\'XSS\');"/>'; echo RemoveXSS($veri);
Dediğimizde çıktısı aşağıdaki gibi olacaktır.
Ali Veli Deli <img src="ja<x>vasc<x>ript:alert('XSS');" />Görüldüğü üzere javascript kelimesinin arasına


Selamlar güzel bir fonksiyon ancak kafama takılan bir durum var,
normalde htmlspecialchars fonksiyonu ile bunun önüne geçilmiyor mu ?
xss üzerine kaba taslak
@ali gündoğdu
Evet dediğiniz fonksiyon ile < ve > karakterleri etkisiz hale getiriliyor lakin uygulamalarda html veri almak gibi bir durumla karşı karşıya geldiğinizde o dediğiniz fonksiyonla bu işi yapmazsınız çünkü tüm html veriyi etkisiz hale getirecektir. Yukarıdaki fonksiyon ise html içindeki zararlıları etkisiz hale getiriyor sadece.
Bu fonksiyon veya yazdığınız kendi fonksiyonları .htaccess dosyasına şu komutu yazarak uygularsak tadından yenmez olur:
php_value auto_prepend_file guvenlik.php
Bu yöntem ile gelen verileriniz önce guvenlik.php dosyanıza uğrar, sonrasında size tertemiz bir halde verilir. get, post, header, session gibi kullanıcıdan gelen ve gelebilecek verileri guvenlik.php dosyasınızda fonksiyonunuza gönderirsiniz, tertemiz bir şekilde alırsınız. Böyle her sayfa içerisinde fonksiyon($_GET) yazmak zorunda kalmazsınız.
strip_tags kulansak olmazmı mı
@serkan
ali gündüzoğluna yazdığım yorumu okuyabilrsin
evet ama strip_tags da ayrıcalık verebiliyosun
@serkan ‘cım
strip_tags ile ayrıcalık verdiğini düşünelim. örneğin bir html veride mutlak suretle img a vb. etiketlere kesinlikle izin vereceksindir. Peki bunlara izin verdiğinde güveni sağlamış olcak mısın ? Şöyle bişey yapsalar ne yapcaksın ?
<img src="javascript:alert(document.cookie);" />ya da
bu durumlarda strip_tags bir işe yaramayacaktır.
Anlatmak istediğim buydu.
doğru haklısın
strip_tags kullanmayın, HTML Purifier sınıfını mutlaka inceleyin.
Yine güzel bir döküman yakında bunu kendi scriptlerime uygularım
bazı kelimeleri de kesiyor bu
multiplayer => multiplayer gibi
mysql_real_escape_string, peki bunu kullanmak yeterli olmuyor mu
@önder
Hayır olmuyor.
brsyuksel yapmış oldugun sistem güzel ama sunucuyu gereksiz yere yorar.
Bu yüzden bence pek tercih edilecek bir şey degil. Tabi basit script iyi sunucu varsa orası ayrı
Yayımladığın şeye muhalefet olmak için söylemiyorum beni yanlış anlama… Ama XSS ‘i önlemek için bence bu kadar abartı bir fonksiyona gerek yok. htmlspecialchars ‘ın yanına sıra javascript ve vbscript kelimelerini str_replace ile javascript ya da java script şeklinde veya daha farklı bir şekilde parçaladıktan sonra rahatlıkla önüne geçilebilir.
Bunun dışında SQL ‘e eklemek için bu tür bir temizlik yapıldıktan sonra mysql_real_escape_string yeterli.
[code]javascript[/code] demiştim ama temizlik yapmış görünen o ki
@firat
o dedikleriniz her zaman işe yaramıyor ne yazık ki googleda xss diye aratırsanız envai çeşit xss saldırıları tekniklerini görebilirsiniz.
Dediğin gibi bir iki araştırma yaptım… Mesela şu site çok kapsamlı: http://ha.ckers.org/xss.html
Buradaki XSS ‘in tamamını Tüm popüler tarayıcılarla denedim (IE 6-7-8, FF 2-3-3.5, Google Chrome, Netscape 8-9, Opera 9, 9.5, 10). Kendi yazdığım fonksiyon tek birisini dahi geçirmedi… Kullandığım Fonksiyon:
function escape_html($html_string, $xss_escape = true)
{
return str_replace(
array(”, ‘”‘),
array(‘<’, ‘>’, ‘"’),
preg_replace(
‘#&(?!(amp;))#s’,
‘&’,
$xss_escape ? preg_replace(‘#(java|vb)script#eis’, ‘”\\1script”‘, $html_string) : $html_string
)
);
}
Bunu sen de test edebilirsin… Test için kullandığım kod: http://rapidshare.com/files/289378596/index.rar
\\1 ile script arasında B HTML açılış ve kapanış tagı mevcut
escape_html(‘%3C%6A%61vascript’); şöle bişey senin güvenliğini ie6 da delip geçecektir.
Bilgilendirme için sağol Raiden…
Rica ederim burda aslında html veri almıyorsak strip_Tags diyerekde geçebiliriz ama uygulamalarda html veri de alacaksak ziyaretçiden haliyle daha sıkı bir güvenlik filtrelemesi gerekiyor.
Evet. Zaten denediğim kadarıyla Services Pack ‘siz IE6 ‘larda bu açık geçiyor… Gerçekten çok vahim bir durum. Daha önce yazdığım siteleri gözden geçirsem iyi olacak.
fonksiyon güzel ve ayrıntılı. html veri almak birçok yerde ihtiyaç. bb kod sistemleri zaman kaybından başka birşey değil. hatta bir çeşit programcı acizliği bile diyebiliriz.
Fırat, o kendi yazdığınız fonksiyonunuzdan ve php’nin fonksiyonları olan htmlspecialchars ve htmlentities vb.. fonksiyonlarından veriyi geldiği gibi geçirmeden önce urldecode() ve htmlspecialchars_decode() geçirmeniz gerek! aksi halde Raiden’in bulduğu gibi açıklar ile delinebilir….
eburhan’ın dediği gibi HTML Purifier sınıfını muhahhak inceleyin hatta kullanın, diğer filtreler yetersiz kalabilir yada gelen veriye zarar verebilir.
Afedersiniz,
Php ile aram pek iyi değil ama XSS açığı olan bir sitem var. Bu kodları config.php’ye koyduğum takdirde bir koruma sağlamam mümkün mü?
verileri bu fonksiyondan geçirmeniz gerekiyor.
Merhaba Raiden,
Yazın hoş,güzel. Fakat biraz balık tutmayı öğretmek yerine balık vermek gibi olmuş seninkisi yeni başlayanlar için.
Benim ricam, bir ara şu preg_match gibi fonksiyonlar içinde kullanılan, mesela preg_replace(‘/${0}\+D/’, …, …); felan gibi kodlardan bahseder misin?
O zaman hakikaten minnettar kalacağım.