SQL Injection

Oke kali ini kita akan sedikit menyambung mengenai tulisan gw sebelumnya mengenai "Sekilas PDO (PHP Data Objects)" yang sekilas menyinggung mengenai PDO. Setelah bertapa 9 bulan 10 hari akhirnya gw bisa mengerti arti mencinta apa itu PDO dan penggunaan dasarnya (masih dasar-dasar saja). Berbicara mengenai PDO sangat erat kaitannya dengan prepared statement. Itulah kenapa dalam tulisan ini gw akan menyinggun terlebih dahulu mengenai Prepared Statement, karena tanpa mempelajari prepared statement kita tidak akan tau tujuan dasar penggunaan PDO itu sendiri dan hal paling membedakan dari hal tersebut. Karena dalam praktik awal gw menggunakan PDO, gw membuat sebuah kesalahan dengan tidak me-preapared statement terlebih dahulu, sehingga walaupun aplikasi berjalan lancar tapi tetap praktik ini mencederai tujuan dasar dan kelebihan utama dari penggunaan PDO.

Dan kenapa image dari artikel ini suntikan? Ya tentu saja karena manfaat besar yang dirasakan developer dalam penggunaan PDO adalah sebagai langkah awal dalam mencegah aplikasi kita disodomi oleh user-user iseng.

 

Prepared Statement

Prepared statements adalah sebuah fitur yang disediakan oleh sebuah Database Management System (DBMS) seperti MySQL, PostgreSQL, Oracle, SQLite, IBM, Firebird, DBLib, dan lain-lain, dimana kita bisa mengirim query secara terpisah dari query utama dan variabel pendukungnya. Prepared Statement adalah salah satu cara untuk melakukan komunikasi ke database yang dikatakan cukup efektif untuk mencegah SQL Injection. Tujuannya, agar query menjadi lebih aman dan cepat (jika perintah yang sama akan digunakan beberapa kali).  Menggunakan prepared statement ini juga sangat disarankan ketika perlu melakukan banyak query supaya tidak terlalu memberatkan sistem.

SQL Injection

Sebagian serangan kepada aplikasi berbasis web dilakukan melalu sql injection. Sebagai gambaran, SQL injection memanfaatkan celah dalam query sql dimana kita menyisipkan suatu perintah query tertentu dalam suatu query yang sudah dibuat oleh pembuat aplikasi. Secara logika gambaran sql inject seperti komik di atas, dimana query yang diinject mengakibatkan query yang disusun oleh pembuat aplikasi tidak berjalan sebagaimana mestinya (atau tidak berjalan sama sekali, dalam banyak kasus justru hanya query yang diinject yang akan dijalankan oleh server. 

Akan tetapi gw tidak akan menjelaskan contoh konkrit penggunaan sql injection, karena gw sendiri masih sangat amat ragu dengan kemampuan keamanan dari banyak aplikasi yang gw buat. Karena dalam membuat aplikasi saat ini gw masih one man show, jadi belum ada yang mau ngetes securitynya.

Implement This In Query

Saat anda membuat suatu perintah dengan menggunakan driver mysql biasanya anda menggunakan query seperti dibawah ini.

 mysql_query("SELECT * FROM building WHERE name = '$name'", $linkfromConnect); 

Penggunaan ini akan rentan terinfeksinya suatu query oleh injeksi query lain yang tidak jarang merusak table kita. Dan ini juga satu alasan kedepan php tidak akan lagi meneruskan pengembangan driver mysql karena banyaknya kelemahan tersebut. Dengan prepared statement, seperti arti harfiahnya, statement sql tersebut akan melalui 3 tahapan yaitu prepare, bind, dan execute.

 

Prepared

Tahap pertama dalam penggunaan prepared statement adalah tentunya memprepared query yang akan kita buat. Disini query akan dibagi menjadi 2 hal, yaitu statement dari query tanpa memasukkan variable data yang akan digunakan. Disini akan saya contohkan penggunaannya dengan mysqli dan pdo.

mysqli

 
// membuat koneksi dengan server dan database
$link = mysqli_connect('SERVER', 'UN', 'PWD', 'DB_NAME'); 
// preparing statements 
$stmt = mysqli_prepare($link, "SELECT * FROM building WHERE name=?"); 

Baris kedua kita mempersiapkan koneksi dengan menggunakan driver mysqli. Sedangkan baris ke 4 kita menuliskan statement yang akan kita gunakan. Perbedaan dasar dengan query sebelumnya adalah, kita tidak memasukkan secara langsung variable data kedalam query, tapi kita hanya memasukkan tanda tanya "?" sebagai tanda bahwa bagian ini akan diisi dengan variable data, bukan sebuah query lainnya. Dengan begitu ini dapat menjadi benteng awal masuknya query racun yang dapat merusak kemaslahatan umat. 

PDO

 
// membuat koneksi dengan server dan database
$pdo = NEW PDO('mysql:SERVER;dbname:DB_NAME', 'UN', 'PWD');
  
// preparing statements
$stmt = $pdo->prepare("SELECT * FROM building WHERE name=:name");

Sama seperti mysqli, hanya saja disini kita menuliskan variable yang akan di bind (ikat) dengan penyebutan variablenya. Apakah bisa kita gunakan tanda tanya seperti mysqli? Dalam menulis params dalam PDO ada 2 cara, yaitu dengan named parameters (seperti yang gw lakukan di contoh), dan question mark (?) parameters (seperti yang gw terapkan pada driver mysqli).

 

Bind Parameters

Langkah selanjutnya adalah mengikat parameter tersebut sebagai parameter. Dalam hal ini semua parameter yang dikirim oleh variable akan dibaca hanya sebagai parameter, tidak dibaca sebagai query yang akan dieksekusi oleh server.

mysqli

 
// membuat koneksi dengan server dan database
$link = mysqli_connect('SERVER', 'UN', 'PWD', 'DB_NAME');
  
// preparing statements
$stmt = mysqli_prepare($link, "SELECT * FROM building WHERE name=?");
 
// data variable
$name="I";
  
// bind data
mysqli_stmt_bind_param($stmt, "s", $name);

Pada tahap ini kita menginput variable data. Variable data ini dapat dari variable lain atau dalam contoh ini langsung saya sebutkan stringnya.

Fungsi mysqli_stmt_bind_param adalah fungsi bind dalam driver mysqli. Ada 3 argumen yang harus kita masukkan dalam fungsi ini. Argumen 1 adalah statement query, argumen 2 adalah data type yang kita kirimkan, dan argumen 3 adalah variable yang kita masukkan. Hal yang harus diperhatikan adalah data type yang kita kirim sebagai variable, lebih lengkap dapat anda lihat pada link fungsi yang ada sebelumnya, sebagai contoh disini saya isi denga "s" yang berarti tipe data berupa string, "i" untuk integer, "d" untuk double, dan "b" untuk boolean.

PDO

// membuat koneksi dengan server dan database
$pdo = NEW PDO('mysql:SERVER;dbname:DB_NAME', 'UN', 'PWD');

// preparing statements
$stmt = $pdo->prepare("SELECT * FROM building WHERE name=:name");

// data variables
$values = array(
 ':name' => 'I',
 );

Pada tahap ini kita membuat variable yang akan kita inputkan dalam stmt. Proses bind dalam PDO sebenarnya belum dilakukan pada statement ini, dan akan sekaligus dilakukan pada tahap berikutnya. Yaitu execute.

Execute

Langkah selanjutnya dan terakhir adalah mengeksekusi preapred query yang telah kita buat.

mysqli

// membuat koneksi dengan server dan database
$link = mysqli_connect('SERVER', 'UN', 'PWD', 'DB_NAME');

// preparing statements
$stmt = mysqli_prepare($link, "SELECT * FROM building WHERE name=?");

// data variable
$name="I";
 
// bind data
mysqli_stmt_bind_param($stmt, "s", $name);
mysqli_stmt_execute($stmt);

Dengan mysqli proses execute dilakukan setelah binding dilakukan.

PDO

// membuat koneksi dengan server dan database
$pdo = NEW PDO('mysql:SERVER;dbname:DB_NAME', 'UN', 'PWD');

// preparing statements
$stmt = $pdo->prepare("SELECT * FROM building WHERE name=:name");

// data variables
$values = array(
 ':name' => 'I',
 );
$stmt -> execute($values);

Execute dalam PDO dilakukan dengan memasukkan argumen variable dalam fungsi execute dalam PDO.


Setelah itu anda bisa langsung melanjutkan fungsi lain seperti fetching data dari hasil eksekusi. Dengan begini aplikasi anda akan sedikit lebih aman dari tangan-tangan jahil.

Mungkin itu dulu yang bisa saya sampaikan, tapi gw masih mencoba menggali lebih jauh mengenai hal ini. Semoga ada yang bisa kalian ambil dari tulisan ini. Kalau ada kekurangan dan kesalahan mohon informasinya agar saya dapat memperbaiki artikel ini. Sekian dari gw, Keep Posting and selamat blogwalking kawan :D


 

Sumber:

http://php.net/

http://www.dewadg.net/2015/02/menggunakan-prepared-statement-dengan-pdo-php/

http://www.duniailkom.com/tutorial-php-mysq-cara-menampilkan-data-dengan-mysqli-prepared-statements/