Sayfayı Yazdır | Pencereyi Kapat

Php Portallarda SQL Ýnj. Güvenliði

Nereden Yazdırıldığı: Bilginin Adresi
Kategori: Bilgisayar Güvenliði / Computer Security
Forum Adı: Güvenlik / Security Makaleleri
Forum Tanımlaması: Bilgisayarýnýzý Her Türlü Saldýrýya Karþý Korumak Ýçin Yapmanýz Gerekenler
URL: https://www.bilgineferi.com/forum/forum_posts.asp?TID=7958
Tarih: 04-05-2024 Saat 16:55


Konu: Php Portallarda SQL Ýnj. Güvenliði
Mesajı Yazan: megabros
Konu: Php Portallarda SQL Ýnj. Güvenliði
Mesaj Tarihi: 23-08-2009 Saat 23:39

Veritabaný kullanýlan uygulamalarda en büyük güvenlik sorunlarýndan biri SQL Injection saldýrýlarýdýr.Bu tip saldýrýlar genellikle, kullanýcýdan gelen verinin filtrelenmeden veya tipinin doðruluðu kontrol edilmeden sorguya sokulmasý sonucu oluþur.

SQL Injection saldýrýlarýný önlemek kolaydýr, ama tespit etmek her programcý için kolay deðildir.Þimdi perdenin arkasýný açalým ve php& MySQL uygulamarýnda ne tür ataklar olabileceðini, nasýl önlem alabileceðimizi görelim…


Bir üyelik sistemi ve login sayfasý düþünün, bu sayfada muhtemelen aþaðýdaki gibi bir sorgu olacak.

SELECT uye,parola FROM uye where uye= ‘$_POST[uye]’ and parola=’$_POST[parola]’

Sistem iþleyiþi normal gibi görünüyor ama saldýrganýn tekinin kullanýcý adýna ?uye=admin’/* girdiðini hayal edin.Sorgu þu hali alacak.
SELECT uye,parola FROM uye WHERE uye=’admin’/* AND parola=”

/* karakteri mysql veritabanýnda yorum satýrý baþlangýcýný ifade eder, dolayýsýyla asýl sorgu, SELECT uye_parola FROM uye WHERE uye=’admin’ haline gelecektir.

Bu tür bir saldýrýyý zararlý karakterleri escape(\\) ederek durdurabilirsiniz.Bu iþi php’de yapan hazýr fonksiyonlar mevcut, örneðin addslashes(), ve mysql_real_escape_string().php manual’den bu fonksiyonlarýn kullanýmlarýyla ayrýntýlý bilgi alabilirsiniz.

SQL Injection konusunda genelde dikkat edilmeyen bir diðer konu da kullanýcýnýn normalde göndermesi gereken integer deðerlerin ( genelde ID ) integer olup olmadýðýnýn kontrol edilmemesidir.

Herhangi üyenin detaylarýný gösteren bir sayfa düþünün;
x.php?uyeid=1 ( Bu adres 1 no’lu uyenin bilgilerini gostersin )

$id = mysql_real_escape_string($id);
$sorgu = “SELECT isim,soyad,bla,bla FROM uyeler WHERE id = $_GET[id]”;

Eminim birçoðunuz zaten yukarýdaki kodun yeterince güvenli olduðunu düþünüyorsunuz fakat deðil.Mysql 4.x ile birlikte mySQL union select destegi vermeye baþladý.

Saldýrganýn tekinin ?id=-1 UNION SELECT 0,uye,parola FROM uye olarak istek yaptýðýný düþünsenize..Birinci – asýl – select sorgusu herhangi bir sonuç döndürmeyeceði için dönen sonuclar saldýrganýn girdigi union select içindeki alanlar olacaktýr.

Dikkatinizi çektiyse týrnak kullanmadan böyle bir saldýrý yapýlabiliyor, dolayýsýyla bu nokta dikkat edilmesi gereken bu tip id tarzý bilgileri sorguya alýrken veri tipini kontrol etmek.

Bunu (int)$degisken veya intval($degisken); seklinde yapabilirsiniz.Ya da is_integer, is_numeric gibi fonksiyonlarla kontrol edip gerekli manual try/catch mekanizmasýný kurabilirsiniz.

Ya da bu tür deðerleri týrnak içine alarak saldýrganýn iþi zorlaþtýrýlabilir.(where id = ‘$id’ gibi) Zira, bu durumda saldýrgan union select sorgularý sokabilmek için ilk önce ilk SELECT sorgusunu bitirmek zorunda kalacak ve UNION SELECT yazmadan önce ‘ karakterini yazacak.Fakat mysql_real_escape_string burda devreye girip ‘ karakterini escape edeceði için olasý saldýrýlar geçersiz hale gelir.

Yani daha güvenli bir kod aþaðýdaki gibi olacak;
$id = intval($_GET[”id”]);
$sorgu = “SELECT * FROM uyeler WHERE id = ‘$id’ “;

SQL injection saldýrýlarý bunlarla sýnýrlý deðil, mysql’nin desteklediði INTO OUTFÝLE ile SQL dumplarýnýz çalýnabilir veya uzaktan php kodlarý çalýþtýrabilinir, load_file() fonksiyonu ile dosyalarýnýzýn, konfigurasyon dosyalarýnýzýn kaynak kodlarý okunabilir..

Bir diðer nokta da ; tarzý sorgunun bitip yeni sorgunun baþladýðýný belirten veritabaný iþaretçileri.mysql_query() bu tip çoklu(multiple) sorgularý desteklemediði için sorun yok, ama SQLite veya PortreSQL ile çalýþýyorsanýz ; karakterine dikkat etmeniz gerekiyor.Zira x.php?id=1;DROP DATABASE uye gibi bir sorgu yazmak zor deðil.

Kýsaca yapýlabilecekler mySQL’nin yapýlabilecekleri ile sýnýrlý.

php programcýsýnýn bu konuda yapmasý gerekenler:

- Kullanýcýdan gelen veriyi salt halde sorguya sokmamak, gerekli filtremeleri mysql_real_escape_string() tarzý fonksiyonlarla yapmak

- Sayýsal deðerleri týrnak içine almak

- Magic_quotes’a güvenmemek ( magic_quotes nasýl olsa escape ediyor, benim bir þey yapmama gerek yok düþüncesi )

- mysql_error() çýktýsýný sadece geliþtirme sürecinde debugging amacýyla kullanmak, zira olasý bir sql hatasýnda ekrana mysql_error() çýktýsý verirseniz saldýrganýn iþini kolaylaþtýrmýþ olursunuz.

Bunlarýn dýþýnda php 5 ile gelen prepared statementlar sayesinde SQL injection saldýrýlarýndan kesin olarak kurturabilirsiniz.Zira bu özellik sayesinde, gelen veriler otomatik olarak sürücü tarafýndan iþleme alýnýp zararlý karakter temizleniyor, hatta veri tipini belirttiðiniz sürece type-casting bile yapabilirsiniz.

Saygýlar..



Sayfayı Yazdır | Pencereyi Kapat