SQL Injection Pada MySQL dan PHP

1. Pendahuluan

Internet saat ini telah berkembang luas. Salah satu faktor pendorong utama adalah diterimanya protokol http dengan bahasa HTML sebagai bahasa baku dalam operasional situs web. Kian hari semakin banyak situs web yang bersifat dinamis, yaitu isinya berubah-ubah sesuai kondisi yang disyaratkan. Dengan demikian peran database, sebagai penyimpan dan pengorganisasi data, kian penting dan menjadi bagian terintegrasi dalam operasional situs web.

Tidak ketinggalan pula bahasa pemrograman berbasis scripting semakin banyak digunakan. Hal ini terkait keluwesan dari bahasa tersebut, yang sifatnya ‘just-in-time compiling’, atau dikompile saat akan dijalankan. Dengan keluwesan tersebut, program web kian mudah dibuat, dijalankan dan dipelihara.

Integrasi web dan database mengundang pula kerawanan baru, yaitu penyisipan (injection)terhadap perintah-perintah untuk query ke dalam database. Penyisipan tersebut bertujuan melakukan operasi yang tidak sah (ilegal) terhadap database, sesuai tujuan si penyusup.

1.1. Database MySQL

MySQL merupakan sistem basis data relasional yang berkembang pesat di era Internet. Hal ini terkait sifatnya yang open source, sehingga dapat digunakan secara gratis mengikuti sistem perijinan yang berlaku. MySQL mengikuti standar bahasa query untuk database, yaitu SQL (Structured Query Language).

MySQL juga dikenal dengan kecepatannya, baik saat koneksi maupun dalam menjalankan perintah ke database. Untuk aplikasi-aplikasi web yang koneksinya terputus-putus (state-less), sehingga perlu berulang kali melakukan koneksi dengan database, hal ini akan sangat membantu. Server Database dengan kelas menengah ke atas, baik dalam penanganan data maupun fasilitas, biasanya lambat dalam proses koneksi, karena sejak awal dirancang dalam kondisi tersambung (state-full).

Gabungan antara gratis dan cepat, menghasilkan database yang paling populer di Internet, sepertinya klaim dalam situsnya mysql.com: “The world’s most popular open source database”.

1.2. Bahasa Pemrograman PHP

PHP (singkatan rekursif dari “PHP: Hypertext Preprocessor”) adalah bahasa scripting untuk berbagai keperluan, merupakan produk open source yang banyak digunakan, terutama digunakan sebagai bahasa pembuatan web (ditanam dalam HTML).

Contoh HTML yang digabungkan dengan PHP:

<html>
    <head>
        <title>Example</title>
    </head>
    <body>
        <?php
        echo "Hi, I'm a PHP script!";
        ?>
    </body>
</html>

PHP banyak digunakan karena tersedia untuk berbagai lingkungan (platform), produk open source sehingga non-komersial, akrab bagi pemrogram (secara bahasa mirip dengan C atau Perl), berdaya guna tinggi dan mudah digunakan (mengambil hal-hal yang baik dari bahasa seperti C dan Perl). Keunggulan utama dari PHP adalah kesederhaannya untuk pemula, tapi juga menawarkan hal-hal yang rumit untuk pemrogram yang berpengalaman.

2. SQL Injection

SQL injection adalah suatu cara untuk menyisipkan perintah SQL melalui input dari situs web. Dengan penyisipan tersebut si pelaku dapat melakukan perintah SQL tertentu yang pada akhirnya dapat memperdaya sistem secara keseluruhan.

Banyak situs yang menerima input dari user dan melakukan query ke database berdasarkan input tersebut. Misalnya ketika user akan login, akan diminta username dan password, selanjutnya dilakukan query ke database. Dengan SQL injection, dimungkinkan untuk merancang suatu input user dan/atau password, sehingga dapat mengubah SQL query yang dibangun, dengan tujuan akhir dapat masuk secara bebas.

2.1. Melewati Pemeriksaan

Salah satu trik yang populer digunakan dalam SQL injection adalah menyisipkan karakter tertentu sehingga SQL yang dijalankan tidak efektif sehingga meniadakan pemeriksaan (mengabaikan where). Misalnya dengan memberikan kutip penutup dan membuat pernyataan logika yang selalu benar (misal 1=1).

Berikut ini adalah contohnya:

<?

$nama = “agus”;

$query = “SELECT * FROM customers WHERE username = ‘$name'”;

echo “Query Normal: ” . $query . “<br>”;

// input user yang menggunakan SQL injection

$name = “‘ OR 1 OR ‘1’ = ‘1”;

$query = “SELECT * FROM customers WHERE username = ‘$name'”;

echo “Query Injection: ” . $query;

?>

Tampilan script di atas adalah :

Query Normal: SELECT * FROM customers WHERE username = ‘agus’

Query Injection: SELECT * FROM customers WHERE username = ” OR 1′ OR

‘1’ = ‘1’

Apabila query normal dijalankan di server SQL tentu saja tidak ada masalah karena akan mencari record dari tabel customers yang terkait dengan username agus. Query tersebut akan mendapatkan data yang diinginkan apabila memang terdapat user agus dan tidak mendapatkan data apabila tidak terdapat user tersebut.

Sedangkan untuk query injection pasti akan selalu mendapatkan paling sedikit satu record / data dari tabel customers. Mengapa hal ini bisa terjadi? Hal ini dikarenakan dalam query injection terdapat perintah ‘OR 1’ yang selalu bernilai TRUE.

2.2. Langsung vs Berkutip

Ketika mencoba apakah SQL injection, bila tidak berhasil maka akan terjadi syntax error. Hal ini menandakan struktur dari SQL yang terbentuk tidak benar dan ditolak oleh server SQL. Dalam hal ini perlu diketahui apakah melakukan penyisipan adalah langsung (misalnya parameter berupa field) atau dengan menambahkan kutip (misalnya untuk parameter berupa string).

Pada penyisipan langsung, seluruh parameter yang dikirimkan akan digunakan dalam membentuk SQL tanpa pengubahan. Hal ini dapat dicoba dengan menambahkan spasi dan kata ‘or’ ke parameter. Bila terjadi kesalahan ini menandakan penyisipan langsung adalah mungkin. Misalnya untuk parameter yang diharapkan berupa angka:

SQLString = “SELECT FirstName, LastName, Title FROM Employees WHERE Employee = “. $_GET[‘intEmployeeID’];

Pada penyisipan dalam kutip, parameter yang dikirimkan akan ditambahkan kutip dalam pembentukan SQL, sehingga untuk menyisipkan SQL perlu ditambahkan kutip penutup awal dan pembuka baru agar SQL yang terbentuk tetap benar. Misalnya bentuk dalam aplikasi seperti ini:

SQLString = “SELECT FirstName, LastName, Title FROM Employees WHERE EmployeeID = ‘”. $_GET[‘strCity’]. “‘”;

Contoh dalam menyisipkan SQL dalam sisip langsung seperti berikut:

http://localhost/simpleunquoted.asp?city=-1 UNION SELECT Otherfield

FROM OtherTable WHERE 1=1

Sedangkan untuk sisip dengan kutip:

http://localhost/simplequoted.asp?city=’UNION SELECT Otherfield

FROM OtherTable WHERE “=’

2.3 Eksekusi Berganda Pada PHP dan MySQL

Lazimnya dalam melakukan penyisipan SQL, diharapkan dapat melakukan query yang tidak terbatas pada select, tapi juga perintah-perintah yang lain, seperti insert, update dan delete. Pada beberapa database eksekusi berbagai perintah dalam 1 kali pemanggilan fungsi adalah mungkin, yaitu dengan memisah tiap-tiap perintah dengan titik-koma (;). Sehingga operasi terhadap database akan semakin rawan karena dimungkinkan menghapus keseluruhan database, meskipun awalnya query tersebut dirancang hanya untuk operasi select.

Beruntung dalam kasus eksekusi perintah berganda ini tidak dimungkinkan dalam PHP, seperti tercantum dalam manual: “multiple queries are not supported”. Dalam kasus terburuk, jebolnya operasi select, setidaknya tidak membuat akses terhadap operasi yang lain (seperti delete) dimungkinkan. Meskipun bila pengecekan hak akses berhasil dilewati, dan kewenangan sebagai administrator diperoleh, hal ini juga menimbulkan kerawanan baru.

2.4. Contoh Pada Login Form

Berikut ini adalah contoh mekanisme SQL injection yang dapat terjadi pada proses login. Misalkan terdapat tabel User yang digunakan untuk menyimpan data user, yang di dalamnya terdapat 2 field yaitu username dan password. Misalkan juga terdapat 2 user yaitu JOKO (password : JOKO) dan AMIR (password : AMIR).

Diberikan form login sebagai berikut.

Login.php

<form method=post action=submit.php>

Nama user <input type=text name=username><br>

Password <input type=text name=password>

<input type=submit name=submit value=Submit>

</form>

Dan file submit.php sebagai berikut.

<?

mysql_connect(“localhost”,”root”,”root”);

mysql_select_db(“test”);

$username = $_POST[‘username’];

$password = $_POST[‘password’];

$query = “SELECT * FROM user WHERE username = ‘$username’ AND password =   ‘$password'”;

echo “$query<br>”;

$hasil = mysql_query($query);

$jmldata = mysql_num_rows($hasil);

if ($jmldata != 0) echo “<h1>Login SUKSES</h1>”;

else echo “<h1>Login GAGAL</h1>”;

?>

Ide dari proses login di atas adalah mencari nama user dan password dalam tabel user berdasarkan username dan password yang dimasukkan melalui form. Perintah mysql_num_rows() akan menghasilkan jumlah record hasil pencarian. Apabila ditemukan nama user dan password yang sesuai maka mysql_num_rows() akan menghasilkan jumlah baris record yang tidak sama dengan 0. Sedangkan apabila tidak ditemukan, jumlah baris record adalah 0.

Selanjutnya jumlah baris record yang muncul tersebut dicek. Login akan berhasil apabila ada record yang ditemukan atau jumlah baris recordnya tidak sama dengan 0, dan akan gagal jika jumlah baris recordnya 0.

Sekarang, perhatikan apa yang terjadi apabila dalam form dimasukkan input sebarang nama user dan password berbentuk ‘ OR 1 OR ‘1’ = ‘1. Proses login akan berhasil karena perintah SQL yang dijalankan adalah :

SELECT * FROM user WHERE username = ‘xxx’

AND password = ” OR 1 OR ‘1’ = ‘1’

yang akan menghasilkan TRUE.

3. Mencegah SQL Injection

Untuk mencegah terjadinya SQL injection dalam PHP yaitu dengan membersihkan input-input yang berasal dari user, di antaranya menggunakan fungsi addslashes atau mysql_real_escape_string. Kedua fungsi ini menambahkan backslash pada tanda kutip, baik kutip tunggal (‘) maupun ganda (“). Dengan demikian input dari user, yang terdapat dalam variabel POST, GET, dan COOKIE, akan dikirim sebagaimana mestinya, sehingga tidak mengacaukan dalam pembentukan SQL.

Sehingga untuk kasus login di atas perintah SQL yang dijalankan adalah :

SELECT * FROM user WHERE username = ‘xxx’

AND password = ‘\’ OR 1 OR \’1\’ = \’1′

sehingga akan menghasilkan FALSE karena password yang dicari adalah \’ OR 1 OR \’1\’ = \’1. Dengan demikian login akan gagal.

PHP juga memiliki setting untuk tanda kutip, yaitu get_magic_quotes_gpc. Bila setting ini adalah ‘on’, maka seluruh input dari POST, GET dan COOKIE secara otomatis akan ditambahkan backslash.

Sebagai catatan, dalam MySQL tanda single quote digunakan sebagai pengapit data / value yang berupa string. Sedangkan backslash single quote merupakan tanda yang digunakan untuk menyatakan karakter single quote.

Script berikut ini adalah modifikasi dari submit.php pada kasus login di atas yang ditambahkan perintah mysql_real_escape_string().

<?

$username = mysql_real_escape_string($_POST[‘username’]);

$password = mysql_real_escape_string($_POST[‘password’]);

$query = “SELECT * FROM user WHERE username = ‘$username’

AND password = ‘$password'”;

?>

4. Penutup

Berkembangnya situs web yang ditandai dengan kemudahan dalam pembuatan perlu dicermati sedemikian rupa sehingga tidak mengabaikan segi keamanan. Input dari user perlu diolah sedemikian rupa sehingga tidak berbahaya atau menimbulkan efek lain dari operasi database yang diharapkan.

Pada MySQL dan PHP, terdapat cara-cara untuk memimalkan hal ini, seperti yang telah dibahas di atas. Meskipun PHP tidak mampu mengeksekusi perintah berganda untuk MySQL, tetapi perlu diwaspadai kerawanan lain dari jebolnya proses otorisasi user.

5. Referensi

  1. Kevin Spett: SQL Injection. © 2005 SPI Dynamics.
  2. Rosihan Ari Yuana: Dasar-dasar Pemrograman PHP, SQL Injection.

1 Komentar »

  1. […] https://oguds.wordpress.com/2008/04/01/sql-injection-pada-mysql-dan-php/ diakses pada 4 Oktober 2016 jam 17.30 WIB […]

RSS feed for comments on this post · TrackBack URI

Tinggalkan Balasan

Isikan data di bawah atau klik salah satu ikon untuk log in:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout / Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout / Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout / Ubah )

Foto Google+

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s