Uzun bir aradan sonra tekrar merhaba! Son zamanın popüler güvenlik fonksiyonu mysql_real_escape_string() makalelerini okudukça şaşırdım, şaşırdıkçada okudum :) En son Ilia Alshanetsy 'nin sitesinde rastladığım makaleye değineceğim. Kendisi PHP Security dalında Chris Shiflett ile fikir alışverişinde bulunan dostlarından biri. Konu şöyle; mysql_real_escape_string() kullanınca veritabanına gidecek veriler için ciddi bir koruma sağladığımızı düşünüyoruz. Ancak Shiflett 'ın bulduğu açığa, Ilia 'nın yaklaşımı ile şu görüntü ortaya çıkıyor: <?php $c = mysql_connect("localhost", "user", "pass"); mysql_select_db("database", $c); // change our character set mysql_query("SET CHARACTER SET 'gbk'", $c); // create demo table mysql_query("CREATE TABLE users ( username VARCHAR(32) PRIMARY KEY, password VARCHAR(32) ) CHARACTER SET 'GBK'", $c); mysql_query("INSERT INTO users VALUES('foo','bar'), ('baz','test')", $c); // now the exploit code $_POST['username'] = chr(0xbf ) . chr(0x27 ) . ' OR username = username /*'; $_POST['password'] = 'anything'; // Proper escaping, we should be safe, right? $user = mysql_real_escape_string($_POST['username'], $c); $passwd = mysql_real_escape_string($_POST['password'], $c); $sql = "SELECT * FROM users WHERE username = '{$user}' AND password = '{$passwd}'"; $res = mysql_query($sql, $c); echo mysql_num_rows($res); // will print 2, indicating that we were able to fetch all records ?> Burada gözüktüğü gibi eğer karakter setimiz Çince ise yaş basmış durumdayız. Burada sorun şu: 0x5c multibyte ında biten, geçerli bir multibyte içeren bütün karakter setlerinde, bu sql enjeksiyonunu yapmak mümkün. Peki sistem nasıl işliyor?mysql_real_escape_string() , Çince karakter setinde geçerli olmayan 0xbf27 multibyte ı (¿’) , 0xbf5c27 (¿’) multibyte 'ına çeviremiyor. Aslında çeviriyor ancak sonuç yine (¿’) oluyor.Yani sql i koruyacak kaçma karakterini ekleyemiyor. Eğer bu kısımı anlamak ta zorlandıysanız kendi sisteminizde şu kodları deneyin, eminim daha açıklayıcı olacaktır: Burada Ilia 'nın önerisi gelişmiş mysql olan MySqli nin yeni versionlarını kullanmak. Yanlız size bir iyi haber vermeden bu makaleyi bitirmek olmaz: "Burada Ulu önderimiz Atatürk'e borcumuz bir kez daha ortaya çıkıyor " Bizim kullandığımız latin alfabesinden dolayı biz bu enjeksiyondan muafız. mysql her halukarda kaçma karakterini koyabiliyor. Çünkü içinde "5c" geçen bir multibyte ımız yok. Tabi (') dışında!! O da zaten mysql in kaçacağı karakter...Bunu mcwebteam in yaptığı karakter tablosundan teğit edebilirsiniz. (birleştirin, kombinasyon deneyin, rand() kullanın, çıkmayacak 5c (') dışında ) Son olarak benim Ilia 'nın blogunda paylaştığım gibi veri girilecek alanlarda karakter sınırlaması yapmak (özellikle kimlik denetimlerinde), her zaman ki en önemli güvenlik önlemlerinden biri. Ancak yine Ilia 'nın cevabı gibi, evet bu işleri zorlaştırır, ancak elbette enjeksiyon hala imkansız değil... |