PHP’de SQL Injection Koruması – 1

Bilindiği üzere php ile en çok kullanılan veritabanı MySQL’dir. Nedeni hem ücretsiz olması hem de yapacağınız projelerin yükünü kaldırabilir olmasıdır. PHP ile geliştirilen bir çok projede girdilerin kontrol edilmemesinden kaynaklanan SQL Injection açığı görülür. Bu yazıda PHP ile SQL Injection Koruma yöntemlerini anlatacağız.

Örnek Olarak Sorgumuz;

SELECT * FROM user WHERE username=’ahmet’ AND password=’123456’

Şeklinde bir sorgumuz var. Biz burada password değerini get ile aldığımızı varsayalım. Normalde post ile alınır ancak dersi daha iyi kavramak açısından böyle yaptım.

<?php
mysql_connect(’localhost’,’root’,’’);
mysql_select_db(’veritabani’);
mysql_set_charset(’utf8’);
$query = mysql_query(“SELECT * FROM user WHERE username=’”.$_GET[’username’].”’ AND password=’”.$_GET[’password’].”’”);
$say = mysql_num_rows($query);
if($say!=0){
$_SESSION[’login’]=’on’;
}
?>

Böyle düşünelim kullanıcı adı ve şifreyi alıp veritabanından kontrol ettiriyor eşleşen var ise login session on oluyor. Şimdi biz bu verileri direk alırsak aşılabilir vaziyette oluyor. Nasıl mı? Login.php olarak kaydedelim yukarıdaki sayfayı.

localhost/login.php?username=’ or username!=’&password=’ or password!=’

Olarak girdiğimiz zaman login olmuş olacağız. Sorgumuz şu hale gelmiş olacak.

SELECT * FROM user WHERE username = ’’ OR username != ’’ AND userpassword = ’’ OR userpassword != ’’

Peki biz nasıl olurda bunun önlemini alırız? Aslında çok basit. WHERE, yani sorgumuz koşullu bölümlerinde şu fonksiyonu kullanacağız.

mysql_real_escape_string()

Sorgumuzun güvenli halde çalışması için,

“SELECT * FROM user WHERE username=’”.mysql_real_escape_string($_GET[’username’]).”’ AND password=’”.mysql_real_escape_string($_GET[’password’]).”’”

Şeklinde olması gerekmektedir. Kısacası SQL injection için alabileceğimiz önlemimiz budur. Bu aşılabilir mi derseniz bilindik yollarla test ettim aşılmıyor. Ancak farklı yolları varmıdır bilmiyorum.

Şimdi veritabanımıza insert ettiğimiz verilere geçelim. Bunları olduğu gibi kaydedersek ekrana basıldığında sayfamızın başka bir sayfaya yönlendirildiğini görebiliriz. Ya da tam sayfa hacked yazılı bir index? Veya bir downloader koyup millete logger bulaştırabilir. Peki biz bunu nasıl engelleriz? Bunu iki şekilde yapabiliriz.

1. INSERT edilecek veriyle oynarız.

2. INSERT eldilen veriyi ellemeyiz ekrana yazacağımız veriyle oynarız.

Peki nasıl?

Bunun için karşı taraf ne yazarsa yazsın kodları çalıştırmadan ekrana basmayı sağlayan fonksiyon htmlentities() fonksiyonumuzdur. Örnek olarak,

test.php

<?php
echo $_GET[’veri’];
?>

Şimdi localhost/test.php?veri=<style> body{background:black;} </style> bunu adres çubuğunda çalıştıralım. Arka plan simsiyah oldu. Tabi bunu veritabanından çektiğini varsayalım. GET ile yapmamın sebebi daha çabuk kavranması için. Bir de şöyle deneyelim.

<?php
echo htmlentities($_GET[’veri’]);
?>

Burada ekrana yazı olarak basacaktır. Herhangi bir kod çalışması söz konusu olmayacaktır. Biz istersek bunu insert edeceğimiz verilerde uygulayabiliriz ya da ekrana basarken uygulayabiliriz. Tabi dikkat edilmesi gereken bir husus var bu noktada. Sayfamızda karakter kodlaması olarak utf-8 kullandığımızı varsayalım.

<?php
echo htmlentities($_GET[’veri’],ENT_QUOTES,’UTF-8’);
?>

Şeklinde kullanıyoruz. Burada Ent_quotes -> çift ve tek tırnakları dönüştür manasında kullanılır. Diğer taraftan utf-8 karakter kodlamasını dönüştürür. Desteklenene karakter listesi aşağıdadır.

ISO-8859-1,ISO-8859-15,UTF-8,KOI8-R,cp866,cp1252,cp1251,BIG5,GB2312,BIG5-HKSCS,Shift_JIS,EUC-JP

Evet verileri rahatlıkla veritabanına kaydedip ekrana basabiliyor ve SQL injectiondan korunmuş oluyoruz.

Bir de not düşeyim. Diyelim veritabanına verileri htmlentities() fonksiyonuyla çevirip kayıt ettik. Panelden düzenleyeceğiz ve kodları text editöre aktaracağız. Aktarırken kodları görmek için html_entity_decode() fonksiyonunu kullanmayı unutmayalım.

Bir önceki yazımız olan cURL ile Birden Fazla Siteye Bağlanma başlıklı makalemizde Çoklu cURL, cURL ile Birden Fazla Siteden Veri Çekme ve cURL ile Birden Fazla Siteye Bağlanma hakkında bilgiler verilmektedir.

About This Author

Uzun yıllardır yazılım ile uğraşıyorum. PHP ile başladığım yazılım hayatıma şu an PHP'nin yanında Swift ve Python ile devam ediyorum. Bu güne kadar bir çok proje geliştirdim ve yeni projeler geliştirmeye de devam ediyorum. Bu sitede yazılımseverlere faydalı bilgiler vermeye, yazılım geliştirmeye, öğrendiklerimi paylaşmaya, yeni başlayanlara yol göstermeye ve onlara yardımcı olmaya çalışıyorum.

Post A Reply