SQL Injection (SQLi), web güvenliğinin en sık rastlanan ve tehlikeli açıklarından biridir. Bir saldırganın, web uygulamasında kullanılan SQL sorgularına kendi zararlı komutlarını eklemesine dayanır. Bu açık, veri tabanı kontrolünü ele geçirme, hassas bilgileri çalma veya sistemi tamamen çökertme gibi ciddi sonuçlar doğurabilir. Şimdi bu konuyu hem teorik hem pratik bir şekilde inceleyelim.
Öncelikle, SQL Injection'ın nasıl çalıştığını anlamak için basit bir örnek düşünelim. Tipik bir login formu şu şekilde bir SQL sorgusu oluşturabilir:
SELECT * FROM users WHERE username = 'user_input' AND password = 'user_password';
Saldırgan, user_input
kısmına şu zararlı girdiyi yazabilir:
' OR '1'='1
Sonuç olarak sorgu şu hale gelir:
SELECT * FROM users WHERE username = '' OR '1'='1' AND password = '';
Bu ne anlama geliyor? '1'='1'
her zaman doğru olduğu için, veri tabanı bu sorguyu çalıştırır ve saldırganı doğrulama olmadan giriş yapmış gibi gösterir.
SQL Injection saldırıları birkaç farklı şekilde yapılabilir. İşte en yaygın türleri:
Sorguya doğrudan zararlı giriş yapılır. Örneğin, yukarıdaki ' OR '1'='1
gibi.
Uygulama, sorgunun sonucunu doğrudan göstermiyor ama dolaylı yanıtlar veriyor. Örneğin:
- Doğru sorgu: Sayfa yüklenir.
- Yanlış sorgu: Sayfa hata verir.
Bu tür SQLi'de, sorguları yavaş yavaş test ederek hassas bilgileri çıkarırsınız.
Saldırgan, veri tabanının diğer tablolarından veri çekmek için UNION
komutunu kullanır:
' UNION SELECT username, password FROM users --
Sorguların sonucunu test etmek için zamanlama tabanlı teknikler kullanılır. Örneğin:
' OR IF(1=1, SLEEP(5), 0) --
Bu saldırıda, uygulamanın yanıt süresi saldırının başarılı olup olmadığını gösterir.
Eğer henüz yapmadıysan DVWA (Damn Vulnerable Web Application) indir ve kur. DVWA, öğrenme ve test amaçlı güvenlik açıklarıyla dolu bir platformdur.
- DVWA’da SQL Injection seviyesini Low olarak ayarla.
- Kullanıcı arama formunda şunu dene:
' OR '1'='1 --
SQL Injection ile yalnızca giriş yapmayı değil, veri tabanını keşfetmeyi de öğrenebilirsin. Şöyle bir sorgu deneyebilirsin:
' UNION SELECT 1, database(), 3 --
Bu sorgu, mevcut veri tabanının adını döndürür.
SQL Injection’ı önlemek için birden fazla yöntem kullanmalıyız. İşte temel savunma mekanizmaları:
Kullanıcı girdisini sorgu dizisinin dışında tutarak zararlı komutların çalışmasını engeller.
Örnek PHP kodu:
$stmt = $conn->prepare("SELECT * FROM users WHERE username = ? AND password = ?");
$stmt->bind_param("ss", $username, $password);
$stmt->execute();
Kullanıcıdan gelen verileri doğrula. Örneğin, yalnızca alfanumerik karakterlere izin ver.
Uygulamanın kullandığı veri tabanı kullanıcı hesabına minimum yetkiler ver. Örneğin, yalnızca SELECT
ve INSERT
yetkisi tanımlanabilir.
Bir WAF, SQL Injection girişimlerini algılayarak otomatik olarak engeller.
SQL Injection, öğrenmesi kolay ama etkisi çok büyük bir açık. İlk başta DVWA gibi güvenli ortamlarda bu saldırı türünü deneyimlemen çok önemli. Ardından gerçek sistemlerde, bu açıkları nasıl tespit edip engelleyebileceğini anlaman gerekir.
Unutma, SQL Injection gibi saldırılar sadece giriş kapısıdır. Bir saldırgan bir kez içeri girdiğinde, sistemin diğer parçalarını da hedef alabilir. Bu yüzden savunmayı bütüncül düşünmelisin.
Hazır olduğunda bir sonraki adıma geçelim: Cross-Site Scripting (XSS). 😊