flawopen.com/SQL Injection di PHP/mysqli vs PDO
MySQLi vs PDO: prepared statement yang aman
Prepared statement menjaga instruksi SQL tetap dan mengirim nilai input terpisah, seperti mengisi kotak berlabel. PDO dan MySQLi sama-sama bisa melakukannya. Keamanan berasal dari binding nilai yang benar, bukan nama library.
Kueri yang sama disiapkan dengan kedua API
$userId = $_GET['id']; $sql = "SELECT id, email FROM users WHERE id = " . $userId; // Both calls execute the already-built SQL string: $rows = $mysqli->query($sql); $rows = $pdo->query($sql);
// PDO $stmt = $pdo->prepare( "SELECT id, email FROM users WHERE id = :id" ); $stmt->execute(["id" => $userId]); // MySQLi $stmt = $mysqli->prepare( "SELECT id, email FROM users WHERE id = ?" ); $stmt->bind_param("i", $userId); $stmt->execute();
Portabilitas database adalah perbedaan utama PDO
PDO menyediakan antarmuka umum untuk beberapa driver; MySQLi berfokus pada MySQL dan MariaDB. PDO tidak otomatis membuat SQL portabel: dialek, perilaku driver, dan fitur tetap berbeda.
PDO dapat memakai placeholder bernama seperti :id atau posisi ?, bergantung driver; jangan mencampurnya dalam satu statement. MySQLi memakai ?. Keduanya mengikat nilai, bukan nama tabel/kolom, kata kunci, atau arah urutan.
Driver PDO dapat memakai prepare native atau emulasi. Pada MySQL, PDO::ATTR_EMULATE_PREPARES mengatur emulasi jika didukung; driver dapat mengemulasi atau fallback saat prepare native tak tersedia/gagal. Ikuti dokumentasi driver. Pengaturan ini tidak mengamankan SQL interpolasi: pertahankan teks tetap dan ikat nilai dalam mode apa pun.
Aturan mencegah SQL Injection pada kedua library
Gunakan prepare() dan ikat setiap nilai tak tepercaya. Pertahankan sintaks SQL; pilih identifier dinamis dari peta server yang ketat atau varian kueri terbatas. Prepared statement tidak mengotorisasi akses baris: batasi kueri ke pengguna terautentikasi bila perlu. Pada LIKE, binding mencegah injeksi sintaks SQL, tetapi % dan _ tetap wildcard kecuali di-escape untuk pencarian literal.
Memilih PDO atau MySQLi
- ✓Pilih PDO bila memerlukan API umum lintas driver; verifikasi dialek SQL dan perilaku driver saat migrasi.
- ✓Pilih MySQLi untuk aplikasi khusus MySQL/MariaDB yang membutuhkan API spesifik MySQL.
- ✓Pada keduanya, audit interpolasi, konkatenasi, dan identifier dinamis; ikat nilai dan otorisasi record secara terpisah.
Pertanyaan umum
Tidak. Keduanya mengikat nilai dengan aman bila kueri dipersiapkan dan nilainya diikat. Nama placeholder dapat lebih mudah dibaca, tetapi tidak mengikat identifier atau menggantikan otorisasi.
Tidak sebagai aturan umum. Dukungan dan fallback driver berbeda. Periksa dokumentasi dan kebutuhan aplikasi. Dalam mode apa pun, pertahankan struktur SQL dan kirim nilai sebagai parameter.
Tidak. Parameter mewakili nilai, bukan identifier atau kata kunci SQL. Petakan pilihan klien ke kumpulan fragmen tepercaya yang terbatas di server.
Referensi
- Manual PHP — PDO Prepared Statements
- Manual PHP — MySQLi Prepared Statements
- Manual PHP — PDO::setAttribute dan emulasi prepare
- FlawOpen — SQL Injection di PHP