SQL Injection, Akibat dan Antisipasinya

SQL Injection adalah kerentanan web yang memungkinkan penyerang mengganggu kueri database pada sistem. Serangan ini biasanya digunakan untuk mengambil isi database dalam sistem. Dalam beberapa kasus, penyerang dapat mengubah atau menghapus data ini, menyebabkan perubahan terus-menerus pada konten atau perilaku aplikasi. Kejadian lain, penyerang dapat meluncurkan serangan SQL Injection untuk mengkompromikan server yang mendasarinya atau infrastruktur back-end lainnya, atau melakukan serangan denial of service.

Dampak Serangan SQL Injection

Serangan SQL Injection yang berhasil dapat menyebabkan akses tidak sah ke data sensitif seperti kata sandi, informasi kartu kredit, atau informasi pengguna pribadi. Dalam beberapa tahun terakhir banyak pelanggaran data profil tinggi dihasilkan dari serangan SQL Injection, yang menyebabkan kerusakan reputasi dan bahkan perusahaan kena denda. Dalam beberapa kasus, penyerang dapat memperoleh kerentanan halaman adminstrator bahkan server yang terus-menerus dalam sistem perusahaan, yang mengakibatkan efek kerugian jangka panjang yang mungkin tidak diketahui dalam waktu yang lama.

Contoh SQL Injection

Kerentanan, serangan, dan metode SQL Injection datang dengan bentuk yang berbeda dalam situasi berbeda. Berikut adalah beberapa contoh umum SQL Injection:

- Mengambil data yang ter-hide, teknik di mana penyerang dapat mengubah kueri SQL untuk mengembalikan hasil tambahan.
- Subverting application logic, teknik di mana penyerang memodifikasi kueri untuk menumbangkan algoritma sistem.
- Serangan UNION, teknik di mana penyerang dapat mengambil data dari beberapa tabel database.
- Periksa basis data, teknik di mana penyerang dapat mengekstrak informasi tentang versi dan struktur database.
- Blind SQL Injection, hasil kueri yang penyerang kendalikan tidak dikembalikan dalam respons sistem.

Mari kita bahas satu persatu contoh umum di atas:

- Mengambil data yang ter-hide

Biasanya, cara ini dilakukan dengan memanfaatkan URL pada browser, umumnya website yang berpeluang kena adalah mereka yang memanfaatkan url untuk ambil sebuah parameter. Contohnya seperti ini:
https://tokoku.com/produk?kategori=Souvenir

URL di atas akan bermakna bahwa sistem menampilkan produk dengan kategori souvenir, atau dalam sintaks sql akan sepert ini:
SELECT * FROM produk WHERE kategori = 'Souvenir' AND status=1

kolom status=1 bermakna bahwa produk yang muncul adalah produk yang siap dijual, jika belum siap dijual atau tidak ada stok maka status=0

Penyerang kemungkinan besar akan melakukan SQL Injection seperti ini:
https://tokoku.com/produk?kategori=Souvenir'--

Modifikasi URL ini akan bermakna:
SELECT * FROM produk WHERE kategori = 'Souvenir'--' AND status=1

Yang mana, dalam SQL tanda ` -- ` berperan sebagai pembuat komentar (sistem tidak akan mengeksekusi sintaks). Itu artinya, sisa sintaks setelah nilai Souvenir maka akan dijadikan komentar, sehingga sistem akan menampilkan semua produk baik yang siap dijual maupun yang belum siap dijual.

Atau bisa juga penyerang melakukan sebuah sintaks seperti ini:
https://tokoku.com/produk?kategori=Souvenir'+OR+1=1--
yang secara SQl akan seperti ini:
SELECT * FROM produk WHERE kategori = 'Souvenir' OR 1=1' AND status=1

Kueri yang dimodifikasi akan mengembalikan semua item yang kategorinya adalah Souvenir, atau 1 sama dengan 1. Karena 1=1 adalah benar, kueri akan mengembalikan semua item.

Untuk meminimalisir penyerangan ini, bisa dengan membatasi peranan URL dalam sistem sebagai parameter.

- Subverting application logic

Biasanya cara ini dilakukan dengan memanfaatkan kolom isian, umumnya website yang berpeluang kena adalah mereka yang ada form login bagi pengunjung atau bahkan admin dalam 1 halaman yang sama.

Di sini, penyerang dapat masuk sebagai pengguna mana pun tanpa kata sandi hanya dengan menggunakan urutan komentar SQL -- untuk menghapus pemeriksaan kata sandi atau memainkan kueri seperti contoh gambar di bawah ini:
Contoh Subverting Application LogicContoh Subverting Application Logic

Makna gambar di atas adalah mengirimkan nama pengguna admin"-- dan kata sandi diisi sembarang menghasilkan kueri berikut:

SELECT * FROM pengguna WHERE username = "admin"-- AND password = 'sembarang'

Kueri ini mengembalikan pengguna yang nama pengguna-nya adalah admin dan si penyerang akan masuk ke sistem.

Untuk meminimalisir penyerangan ini, bisa dengan membatasi karakter yang diinput user saat melakukan isian pada form.

- Serangan UNION

Yang ketiga dari serangan SQL injection menggunakan sistem union karena akan menggabungkan dua atau lebih perintah query. Contohnya adalah sebagai berikut:
SELECT * FROM user WHERE id='111' UNION SELECT * FROM member WHERE id='admin'--' AND password='1234'

- Memeriksa Database

Setelah identifikasi awal kerentanan injeksi SQL, biasanya berguna untuk mendapatkan informasi dari database itu sendiri. Informasi ini seringkali dapat membuka jalan untuk eksploitasi lebih lanjut. Kamu bisa meminta informasi versi database. Cara ini dilakukan bergantung pada tipe database, sehingga kamu dapat mengetahui tipe database yang mana teknik yang bekerja. Misalnya, di SQL Injection dapat menjalankan:

SELECT * FROM v$version

Kamu juga dapat menentukan tabel database mana yang ada dan kolom mana yang dikandungnya. Misalnya, di sebagian besar database, kamu dapat menjalankan kueri berikut untuk mencantumkan tabel:

SELECT * FROM information_schema.tables

- Blind SQL Injection

Blind SQL Injection merupakan teknologi pemanfaatan database yang berbeda dengan SQL injection biasa, Normal SQL Injection akan mengeluarkan nilai, sedangkan Blind SQL Injection tidak akan mengeluarkan nilai apapun. Untuk mengetahui nilainya, kita harus melakukan trial and error untuk menguji apakah nilainya benar atau salah.

 

Cara Deteksi Kerentanan SQL

Injeksi SQL dapat dideteksi secara manual menggunakan serangkaian pengujian sistem untuk setiap titik masuk dalam aplikasi. Ini biasanya melibatkan:

  • Kirim karakter kutipan tunggal dan cari kesalahan atau anomali lainnya.
  • Kirimkan beberapa sintaks kustom SQL yang mengevaluasi ke nilai dasar (mentah) dari titik masuk dan nilai yang berbeda, dan cari perbedaan sistem dalam respons aplikasi yang dihasilkan.
  • Kirim kondisi boolean, seperti OR 1=1 dan OR 1=2, dan cari perbedaan dalam respons aplikasi.
  • Kirim muatan yang dirancang untuk memicu penundaan waktu saat dijalankan dalam kueri SQL, dan cari perbedaan waktu yang diperlukan untuk merespons.
  • Memberikan muatan OAST yang dirancang untuk memicu interaksi jaringan out-of-band saat dijalankan dalam kueri SQL, dan memantau setiap interaksi yang dihasilkan.

Ada begitu banyak cara lainnya untuk mendeteksi dan mengeksploitasi kerentanan injeksi SQL bekerja secara identik pada berbagai jenis database. Namun, ada sintaks yang berbeda pada tiap bahasa database, SQL dengan NoSQL, Oracle dengan SQL, dan lain sebagainya umumnya memiliki sintaks yang mirip-mirip. Sebagai contoh:

  • Sintaks untuk penggabungan string.
  • Komentar.
  • Kueri berkelompok (atau bertumpuk).
  • API khusus platform.
  • Pesan kesalahan.

Lalu, bagaimana cara mencegahnya?

Sebagian besar kasus injeksi SQL dapat dihindari dengan menggunakan kueri berparameter (juga dikenal sebagai pernyataan yang disiapkan) alih-alih menggabungkan string ke dalam kueri. Kode berikut rentan terhadap injeksi SQL karena input pengguna digabungkan langsung ke dalam kueri:

`
String query = "SELECT * FROM produk WHERE kategori = '"+ input + "'";
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(query);
`

Kode ini dapat dengan mudah ditulis ulang dengan cara yang mencegah input pengguna mengganggu struktur kueri:
`
PreparedStatement statement = connection.prepareStatement("SELECT * FROM produk WHERE kategori = ?");
statement.setString(1, input);
ResultSet resultSet = statement.executeQuery();
`

Kueri parametrik dapat digunakan dalam situasi apa pun di mana input yang tidak dapat diandalkan muncul sebagai data dalam kueri, termasuk klausa dan nilai WHERE dalam pernyataan INSERT atau UPDATE. Mereka tidak dapat digunakan untuk menangani input yang tidak dapat diandalkan di bagian lain kueri, seperti nama tabel atau kolom atau ORDER BY. Fungsionalitas aplikasi yang menempatkan data tidak tepercaya di bagian permintaan ini harus menggunakan pendekatan yang berbeda, seperti memasukkan nilai input yang diizinkan ke daftar putih atau logika yang berbeda, untuk melakukan tindakan yang diperlukan.

Untuk menghindari injeksi SQL secara efektif untuk kueri parameter, string yang digunakan dalam kueri harus selalu berupa konstanta keras dan tidak boleh berisi data variabel dari asal mana pun. Jangan tergoda untuk memutuskan berdasarkan kasus per kasus apakah item data dapat dipercaya, tetapi tetap gunakan penggabungan string jika dianggap aman. Sangat mudah untuk membuat kesalahan tentang kemungkinan asal data atau perubahan kode lain yang melanggar asumsi data yang terkontaminasi.

Referensi:
- http://www.aliencoders.org/content/sql-injection-authentication-bypass-cheat-sheet/

https://owasp.org/www-community/attacks/SQL_Injection