Mengamankan Aplikasi Terhadap SQL Injection

SQL Injection dapat dengan mudah diatasi dalam kebanyakan bahasa pemrograman yang menargetkan aplikasi website atau menawarkan fungsi. Dalam DBI di Perl, metode DBI::quote meloloskan karakter-karakter khusus (anggaplah variabel $sql menyimpan referensi ke sebuah objek DBI):
$query = $sql->prepare
(
   "select * from pengguna where nama = "
   .
   $sql->quote($nama_pengguna)
);
Namun begitu, secara umum ini bukan jalan yang terbaik dalam menghadapi masalah tersebut. DBI mengizinkan penggunaan placeholder, yang memperbolehkan Anda untuk mengikat data ke sebuah pernyataan secara terpisah dari pendefinisian pernyataan SQL tersebut. Untuk database yang tidak mendukung placeholder, DBI menirukannya dengan menggunakan fungsi DBI::quote secara otomatis pada nilai-nilai. Banyak sistem database yang mendukung pengikatan nilai secara terpisah melalui API mereka; DBI akan menggunakan dukungan placeholder asli tersebut dalam hal ini. Sebagai contoh:
$query = $sql->prepare("select * from tb_users where username = ?");
$query->execute($username);
Keuntungannya adalah Anda tidak perlu mengingat untuk menggunakan DBI::quote kepada setiap nilai. Nilai-nilai akan diikat secara terpisah, atau dikutip secara benar, tergantung pada dukungan yang ditawarkan oleh SMBD tertentu yang Anda gunakan. Anda kemudian terhindari dari masalah dasar SQL Injection di mana nilai-nilai diinterpretasi sebagai SQL.

Bagi sistem database yang mendukung placeholder secara asli, seringkali ada keuntungan kinerja yang nyata untuk menggunakan placeholder, karena database dapat menyimpan cache dari sebuah perwakilan pernyataan yang terkompilasi dan menggunakannya secara berulang di antara pelaksanaan-pelaksanaan dengan nilai-nilai ikatan yang berbeda. Placeholder kadang-kadang juga disebut sebagai "variabel pengikat".

Dalam PHP, terdapat beberapa fungsi bawaan yang berbeda untuk digunakan pada SMBD yang berbeda untuk meloloskan nilai-nilai yang cocok untuk diimbuhkan dalam pernyataan-pernyataan SQL. Untuk MySQL, yang serupa dengan ini adalah fungsi bawaan mysql_real_escape_string:
$query_result = mysql_query(
   "select * from tb_users where username = '".
   mysql_real_escape_string($username)
   ."'"
);
Antarmuka asli untuk sebuah SMBD tertentu dapat juga menawarkan sebuah metode untuk melakukan pengikatan placeholder secara terpisah, misalnya mysql_stmt_bind_param atau oci_bind_by_name. Selain itu, sebuah pustaka abstraksi database dapat digunakan untuk menirukan placeholder dalam cara yang mirip dengan DBI dari Perl. Sebuah contoh dari beberapa pustaka yang ada ialah ADOdb.

Perbaikan database
Mengatur hak-hak keamanan pada database ke kebutuhan yang paling minim adalah sebuah perbaikan yang sederhana. Tidak banyak aplikasi yang memerlukan pengguna untuk memiliki hak menghapus sebuah tabel atau database.

Kebanyakan database juga menawaran kemampuan untuk menyiapkan pernyataan-pernyataan SQL pada lapisan database melalui stored procedure. Daripada menggunakan sebuah lapisan aplikasi untuk merangkai SQL secara dinamis, stored procedure membungkus prosedur-prosedur database pakai-ulang yang dipanggil dengan parameter-parameter bertipe. Ini menyediakan beberapa keuntungan keamanan dengan membuat masukan-masukan menjadi parameter dan mewajibkan tipe pada mereka, masukan pengguna secara efektif tersaring. Sebagai tambahan, kebanyakan database mengizinkan stored procedure untuk berjalan di bawah hak-hak keamanan yang berbeda daripada pengguna database. Misalnya, sebuah aplikasi akan memiliki akses untuk menjalankan sebuah stored procedure, tetapi tidak memiliki akses ke tabel-tabel dasarnya. Ini membatasi kemampuan aplikasi untuk melakukan sesuatu yang di luar aksi-aksi yang dituliskan di dalam stored procedure.

Yang juga penting untuk dicatat adalah metode query standar dari pustaka client C MySQL tidak akan mengizinkan lebih daripada sebuah query dalam sebuah masukan. Namun begitu, masukan pengguna baik-baik yang mengandung karakter-karakter pelolos (misalnya tanda kutip tunggal) tetap dapat menyebabkan aplikasi tidak berjalan karena sintaks SQL yang buruk. Bahkan beberapa serangan juga mungkin terjadi, sebagai contoh misalkan sebuah situs website yang memperlihatkan sebuah daftar barang untuk sebuah nama pengguna yang dikenal. Query yang dijalankan adalah:
SELECT * from tb_barang where nama_barang='$nama_barang';
Seorang penyerang dapat memakai nama barang yang dirangkai secara khusus untuk mengetahui semua barang milik semua pengguna:
$namapengguna = "' or namapengguna is not null or namapengguna='";
Menghasilkan pernyataan SQL sebagai berikut:
SELECT * from tb_barang where nama_barang='' or nama_barang is not null or nama_barang='';
Ingatlah, walaupun begitu, bahwa meloloskan atau menghapus tanda kutip tidak melenyapkan risiko SQL Injection sepenuhnya. Misalkan query Anda tampak seperti ini:
SELECT * from tb_barang where id_barang=$id_barang;
Dengan anggapan bahwa $id_barang merupakan nilai numerik tetapi dibiarkan lolos tanpa diperiksa, $id_barang yang dirangkai khusus ini akan, sekali lagi, memperlihatkan semua barang milik semua pengguna:
$id_barang = "33 or id_barang is not null or user_id=44";
Yang seperti dapat Anda lihat, tidak mengandung tanda kutip sama sekali dan akan menghasilkan query ini:
SELECT * from tb_barang where id_barang=33 or id_barang is not null or user_id=44;
Pertahanan yang terbaik, daripada membuat daftar hitam masukan buruk yang diketahui, adalah hanya mengizinkan masukan baik yang diketahui, atau, dengan kata lain, membuat daftar putih. Misalnya, jika Anda ingin bertahan terhadap serangan ini, Anda dapat memeriksa variabel id_barang untuk memastikan bahwa isinya numerik seperti berikut:
if(!ctype_digit($id_barang)) {
   die("Karakter-karakter yang tidak sah dalam id_barang.");
}

Sumber : https://id.wikipedia.org/ 

Share this

Related Posts