Dizgeleri birbirine yapıştırarak kurulan bir sorgu, sizin buyruklarınızı bir başkasının verisiyle karıştırır. Veritabanı hangisinin hangisi olduğunu ayırt edemez - böylece özenle seçilmiş bir değer, değer olmaktan çıkıp sorunun bir parçası olur.
// wrong, and it is wrong even if you escape
$sql = "SELECT * FROM users WHERE email = '" . $email . "'";
Çare kaçış değildir
Kaçış, tehlikeli veriyi güvenli kılmaya çalışır. Hazır deyimler ise veriyi AYRI OLARAK ULAŞTIRIR; böylece veri hiçbir zaman buyruk olarak okunamaz. Veritabanına önce soru, sonra değerler söylenir.
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = ?');
$stmt->execute([$email]);
Bir yer tutucunun olamayacağı şeyler
Bir yer tutucu bir DEĞERİN yerini tutar. Bir tablo adının, bir sütun adının ya da bir sıralama yönünün yerini tutamaz - onlar sorunun parçasıdır. Bunların girdiden gelmesi gerekiyorsa, kendi yazdığınız bir listeye karşı denetleyin.
$allowed = ['created_at', 'total', 'status'];
$sort = in_array($in, $allowed, true) ? $in : 'created_at';
$sql = "SELECT * FROM orders ORDER BY $sort DESC";
Sizde olanları bulun
grep -rn "SELECT.*\$_\(GET\|POST\|REQUEST\)" --include="*.php" . | head
Dizgenin içinde bir süperglobal barındıran her sorgu, aranan örüntüdür. Genelde bir avuç tanedirler ve genelde eskidirler.
Ve ikinci savunma hattı
Uygulama kullanıcısına yalnızca ihtiyacı olanı verin - tek bir veritabanı üzerinde dört fiil. Tablo silemeyen bir hesap üzerinden başarılı olan bir enjeksiyon, silebilen bir hesap üzerinden olandan çok daha az zarar verir.