Web uygulamalarında en eski ve hâlâ en yaygın açıklardan biri SQL injection. Kullanıcıdan gelen metni doğrudan sorguya yapıştırdığında, saldırgan sorgunun anlamını değiştirebilir.
Yapma: string birleştirme
Aşağıdaki kod ?email=' OR '1'='1 gibi bir girdiyle tüm kullanıcıları döndürür.
<?php
// ASLA böyle yazma
$email = $_GET['email'];
$sql = "SELECT * FROM users WHERE email = '$email'";
$rows = $pdo->query($sql)->fetchAll();Yap: hazırlanmış ifade
Sorgu ile veri birbirinden ayrı gönderilir; veri hiçbir zaman SQL olarak yorumlanmaz.
<?php
$pdo = new PDO('mysql:host=localhost;dbname=site;charset=utf8mb4', 'user', 'pass', [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => false,
]);
$stmt = $pdo->prepare('SELECT id, name FROM users WHERE email = :email LIMIT 1');
$stmt->execute([':email' => $_GET['email'] ?? '']);
$user = $stmt->fetch(PDO::FETCH_ASSOC);Tablo tasarımı
Güvenlik sadece koddan ibaret değil; benzersiz kısıtlar ve doğru indeksler de hataları erken yakalar:
CREATE TABLE users (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
email VARCHAR(190) NOT NULL UNIQUE,
name VARCHAR(80) NOT NULL,
password_hash VARCHAR(255) NOT NULL, -- password_hash() çıktısı
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);Kontrol listesi
- Parolaları
password_hash()ile sakla. - Veritabanı kullanıcısına yalnızca gereken yetkileri ver.
- Hata mesajlarını son kullanıcıya gösterme.

