Kueri yang disusun dengan menempelkan untai mencampur perintah Anda dengan data orang lain. Basis datanya tak bisa membedakan mana yang mana - sehingga sebuah nilai yang dipilih dengan cermat berhenti menjadi nilai dan berubah jadi bagian dari pertanyaannya.
// wrong, and it is wrong even if you escape
$sql = "SELECT * FROM users WHERE email = '" . $email . "'";
Perbaikannya bukan pelolosan karakter
Pelolosan karakter berusaha membuat data berbahaya menjadi aman. Pernyataan tersiap membuat datanya TIBA SECARA TERPISAH, sehingga ia sama sekali tak bisa dibaca sebagai perintah. Basis datanya diberi tahu pertanyaannya lebih dulu, baru kemudian nilainya.
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = ?');
$stmt->execute([$email]);
Apa yang tak bisa diwakili sebuah penampung
Sebuah penampung mewakili sebuah NILAI. Ia tak bisa mewakili nama tabel, nama kolom, atau arah pengurutan - semua itu bagian dari pertanyaannya. Kalau semua itu harus datang dari masukan, periksa terhadap daftar yang Anda tulis sendiri.
$allowed = ['created_at', 'total', 'status'];
$sort = in_array($in, $allowed, true) ? $in : 'created_at';
$sql = "SELECT * FROM orders ORDER BY $sort DESC";
Temukan yang ada pada Anda
grep -rn "SELECT.*\$_\(GET\|POST\|REQUEST\)" --include="*.php" . | head
Setiap kueri yang di dalam untainya ada superglobal adalah polanya. Biasanya ada segenggam saja dan biasanya sudah tua.
Dan lapis pertahanan kedua
Beri pengguna aplikasi itu hanya yang dibutuhkannya - empat kata kerja pada satu basis data. Injeksi yang berhasil lewat akun yang tak bisa menghapus tabel merusak jauh lebih sedikit daripada lewat akun yang bisa.