- Puanlar
- 5680
- Başarılar
- 8
- New
- #1
🔐 SQL Injection Nedir ve Nasıl Engellenir?
SQL Injection (SQLi), bir web uygulamasında kullanıcıdan alınan verilerin, yeterince temizlenmeden SQL sorgusu içinde kullanılması sonucu ortaya çıkan ciddi bir güvenlik açığıdır. Bu açık sayesinde saldırganlar veritabanını okuyabilir, silebilir hatta yönetici panelini ele geçirebilir.
Bu makalede SQL açığını kapatmanın kesin ve doğru yöntemlerini adım adım göstereceğim.
🚨 1. Asla Yapmamanız Gereken Şey (Çok Tehlikeli!)
Aşağıdaki gibi bir kod ASLA kullanılmamalıdır:
// ÖLÜMCÜL HATA - KULLANMA! $email = $_POST['email']; $sifre = md5($_POST['sifre']); $sql = "SELECT * FROM kullanicilar WHERE email = '$email' AND sifre = '$sifre'"; $sonuc = mysqli_query($baglanti, $sql);
Bu kod, saldırganın giriş yapmasına bile izin verebilir. Örneğin e-posta kutusuna şunu yazmak yeterlidir:
[email protected]' OR '1'='1
✅ 2. Doğru Çözüm: Prepared Statements (Hazır Sorgular)
En güvenli yöntem PDO (PHP Data Objects) kullanarak hazır sorgular oluşturmaktır.
🔹 PDO ile Güvenli Giriş Kontrolü:
// Veritabanı bağlantısı
$dsn = "mysql:host=localhost;dbname=test;charset=utf8mb4";
$pdo = new PDO($dsn, "kullaniciadi", "sifre");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// Güvenli sorgu (Prepared Statement)
$stmt = $pdo->prepare("SELECT * FROM kullanicilar WHERE email = :email");
$stmt->execute(['email' => $_POST['email']]);
$kullanici = $stmt->fetch();
if ($kullanici && password_verify($_POST['sifre'], $kullanici['sifre'])) {
echo "Giriş başarılı!";
} else {
echo "Hatalı e-posta veya şifre.";
}
🔐 3. Şifreleri MD5 ile Saklamayın!
MD5 çok hızlı çalıştığı için kırılması kolaydır. Mutlaka password_hash() kullanın.
// Kayıt olurken:
$hash = password_hash($_POST['sifre'], PASSWORD_DEFAULT);
// Giriş yaparken:
if (password_verify($girilen_sifre, $veritabanindaki_hash)) {
// şifre doğru
}
🛡️ 4. Ek Güvenlik Önlemleri (Katmanlı Savunma)
- ✔️ HTTPS kullanın (şifreler yolda dinlenmesin).
- ✔️ Web sunucusunda mod_security gibi bir WAF kullanın.
- ✔️ Veritabanı kullanıcısına minimum yetki verin (sadece INSERT/SELECT yetkisi).
- ✔️ Hata raporlarını kapatın (
display_errors = Off). - ✔️ Kullanıcı girdilerini asla olduğu gibi sorguya eklemeyin.
📌 5. Özet – Unutmayın!
| YANLIŞ | DOĞRU |
|---|---|
| "SELECT * FROM users WHERE id = $id" | $pdo->prepare("SELECT * FROM users WHERE id = ?") |
| MD5 ile şifre saklama | password_hash() + password_verify() |
| Blacklist (yasak kelime engelleme) | Prepared statements (kesin çözüm) |
⚠️ Not: İnternette gördüğünüz "bir kod yapıştır SQL açığını kapatır" türü çözümlerin neredeyse tamamı ya eksiktir ya da tamamen işe yaramaz. Tek kesin çözüm Prepared Statements + Parametreli Sorgular'dır.
📖 Kaynaklar:
- OWASP SQL Injection
- PHP Prepared Statements