SQL - Injeksi

Jika Anda mengambil input pengguna melalui halaman web dan memasukkannya ke dalam database SQL, ada kemungkinan Anda telah membiarkan diri Anda terbuka lebar untuk masalah keamanan yang dikenal sebagai SQL Injection. Bab ini akan mengajari Anda cara membantu mencegah hal ini terjadi dan membantu Anda mengamankan skrip dan pernyataan SQL di skrip sisi server Anda seperti PERL Script.

Injeksi biasanya terjadi saat Anda meminta masukan dari pengguna, seperti nama mereka dan alih-alih nama, mereka memberi Anda pernyataan SQL yang tanpa sadar akan Anda jalankan di database. Jangan pernah mempercayai data yang diberikan pengguna, proses data ini hanya setelah validasi; sebagai aturan, ini dilakukan olehPattern Matching.

Pada contoh di bawah ini, name dibatasi untuk karakter alfanumerik ditambah garis bawah dan dengan panjang antara 8 dan 20 karakter (ubah aturan ini sesuai kebutuhan).

if (preg_match("/^\w{8,20}$/", $_GET['username'], $matches)) {
   $result = mysql_query("SELECT * FROM CUSTOMERS 
      WHERE name = $matches[0]");
} else {
   echo "user name not accepted";
}

Untuk mendemonstrasikan masalahnya, pertimbangkan kutipan ini -

// supposed input
$name = "Qadir'; DELETE FROM CUSTOMERS;";
mysql_query("SELECT * FROM CUSTOMSRS WHERE name='{$name}'");

Panggilan fungsi seharusnya mengambil record dari tabel CUSTOMERS dimana kolom name cocok dengan nama yang ditentukan oleh pengguna. Dalam keadaan normal,$namehanya akan berisi karakter alfanumerik dan mungkin spasi, seperti string ilia. Tapi di sini, dengan menambahkan kueri yang sama sekali baru ke $ name, panggilan ke database berubah menjadi bencana; kueri DELETE yang dimasukkan menghapus semua catatan dari tabel PELANGGAN.

Untungnya, jika Anda menggunakan MySQL, file mysql_query()function tidak mengizinkan query stacking atau mengeksekusi beberapa query SQL dalam satu panggilan fungsi. Jika Anda mencoba untuk menumpuk kueri, panggilan gagal.

Namun, ekstensi database PHP lainnya, seperti SQLite dan PostgreSQL dengan senang hati melakukan kueri bertumpuk, mengeksekusi semua kueri yang disediakan dalam satu string dan menciptakan masalah keamanan yang serius.

Mencegah Injeksi SQL

Anda dapat menangani semua karakter escape dengan cerdas dalam bahasa skrip seperti PERL dan PHP. Ekstensi MySQL untuk PHP menyediakan fungsi tersebutmysql_real_escape_string() untuk menghindari karakter input yang khusus untuk MySQL.

if (get_magic_quotes_gpc()) {
   $name = stripslashes($name);
}
$name = mysql_real_escape_string($name);
mysql_query("SELECT * FROM CUSTOMERS WHERE name='{$name}'");

The LIKE Quandary

Untuk mengatasi masalah LIKE, mekanisme pelolosan khusus harus mengonversi karakter '%' dan '_' yang disediakan pengguna menjadi literal. Menggunakanaddcslashes(), fungsi yang memungkinkan Anda menentukan rentang karakter yang akan diloloskan.

$sub = addcslashes(mysql_real_escape_string("%str"), "%_");
// $sub == \%str\_
mysql_query("SELECT * FROM messages 
   WHERE subject LIKE '{$sub}%'");