1. Apa yang dimaksud dengan serangan injeksi SQL?
Yang disebut serangan injeksi SQL berarti penyerang memasukkan perintah SQL ke dalam kolom input formulir Web atau string kueri permintaan halaman, dan menipu server agar menjalankan perintah SQL berbahaya. Dalam beberapa bentuk, masukan pengguna digunakan secara langsung untuk membuat (atau mempengaruhi) perintah SQL dinamis, atau sebagai parameter masukan untuk prosedur tersimpan. Bentuk seperti itu sangat rentan terhadap serangan injeksi SQL. Proses serangan injeksi SQL yang umum meliputi:
⑴ Aplikasi Web ASP.NET memiliki halaman login. Halaman login ini mengontrol apakah pengguna memiliki hak untuk mengakses aplikasi. Halaman ini mengharuskan pengguna memasukkan nama dan kata sandi.
⑵ Konten yang dimasukkan di halaman login akan langsung digunakan untuk membuat perintah SQL dinamis, atau langsung digunakan sebagai parameter prosedur tersimpan. Berikut ini contoh aplikasi ASP.NET yang membuat kueri:
System.Text.StringBuilder query = new System.Text.StringBuilder(
"PILIH * dari Pengguna WHERE login = '")
.Append(txtLogin.Text).Append("' DAN kata sandi='")
.Append(txtPassword.Text).Append("'");
⑶ Penyerang memasukkan sesuatu seperti "' atau '1'='1" di kotak input nama pengguna dan kata sandi.
⑷ Setelah masukan konten oleh pengguna dikirimkan ke server, server menjalankan kode ASP.NET di atas untuk membuat perintah SQL untuk menanyakan pengguna. Namun, karena masukan konten oleh penyerang sangat khusus, maka perintah SQL terakhir menjadi: SELECT * from Users WHERE login = '' atau '1'='1' AND password = '' atau '1'='1'.
⑸ Server menjalankan query atau proses tersimpan untuk membandingkan informasi identitas yang dimasukkan oleh pengguna dengan informasi identitas yang disimpan di server.
⑹ Karena perintah SQL sebenarnya telah dimodifikasi oleh serangan injeksi dan tidak dapat benar-benar mengautentikasi identitas pengguna, sistem akan memberikan otorisasi yang salah kepada penyerang.
Jika penyerang mengetahui bahwa aplikasi akan menggunakan konten yang dimasukkan dalam formulir secara langsung untuk kueri verifikasi identitas, ia akan mencoba memasukkan beberapa string SQL khusus untuk merusak kueri guna mengubah fungsi aslinya dan mengelabui sistem agar memberikan izin akses.
Tergantung pada lingkungan sistem, kerusakan yang mungkin ditimbulkan oleh penyerang juga berbeda-beda, yang terutama ditentukan oleh izin keamanan aplikasi untuk mengakses database. Jika akun pengguna memiliki hak administrator atau hak lanjutan lainnya, penyerang dapat melakukan berbagai operasi pada tabel database yang ingin ia lakukan, termasuk menambah, menghapus atau memperbarui data, atau bahkan menghapus tabel secara langsung.
2. Bagaimana cara mencegahnya?
Untungnya, tidak terlalu sulit untuk mencegah aplikasi ASP.NET dibobol oleh serangan injeksi SQL. Yang perlu Anda lakukan hanyalah memfilter semua konten masukan sebelum menggunakan konten masukan formulir untuk membuat perintah SQL. Penyaringan masukan dapat dilakukan dengan berbagai cara.
⑴ Untuk situasi di mana kueri SQL dibuat secara dinamis, teknik berikut dapat digunakan:
Pertama: Ganti tanda kutip tunggal, yaitu mengubah semua tanda kutip tunggal menjadi dua tanda kutip tunggal untuk mencegah penyerang mengubah arti perintah SQL. Melihat contoh sebelumnya lagi, "SELECT * from Users WHERE login = ''' or ''1''=''1' AND password = ''' or ''1''=''1'" jelas akan mendapatkan sama "SELECT * from Users WHERE login = '' or '1'='1' AND password = '' or '1'='1'" beda hasilnya.
Kedua: Hapus semua tanda hubung di konten masukan pengguna untuk mencegah penyerang membuat kueri seperti "SELECT * from Users WHERE login = 'mas' -- AND password =''", karena akhiran kueri tersebut Setengahnya telah dikomentari keluar dan tidak valid lagi. Penyerang hanya perlu mengetahui nama login pengguna yang sah dan tidak perlu mengetahui kata sandi pengguna agar berhasil mendapatkan akses.
Ketiga: Batasi izin akun database yang digunakan untuk menjalankan kueri. Gunakan akun pengguna yang berbeda untuk melakukan operasi kueri, penyisipan, pembaruan, dan penghapusan. Dengan mengisolasi operasi yang dapat dilakukan oleh akun yang berbeda, ini mencegah tempat yang awalnya digunakan untuk menjalankan perintah SELECT digunakan untuk menjalankan perintah INSERT, UPDATE, atau DELETE.
⑵ Gunakan prosedur tersimpan untuk menjalankan semua pertanyaan. Cara penyampaian parameter SQL akan mencegah penyerang menggunakan tanda kutip tunggal dan tanda hubung untuk melakukan serangan. Selain itu, ini juga memungkinkan izin database dibatasi untuk hanya mengizinkan prosedur tersimpan tertentu untuk dijalankan. Semua input pengguna harus mematuhi konteks keamanan dari prosedur tersimpan yang disebut, sehingga serangan injeksi sulit terjadi.
⑶ Batasi panjang input formulir atau string kueri. Jika nama login pengguna hanya memiliki maksimal 10 karakter, jangan menerima lebih dari 10 karakter yang dimasukkan dalam formulir. Hal ini akan sangat meningkatkan kesulitan bagi penyerang untuk memasukkan kode berbahaya ke dalam perintah SQL.
⑷ Periksa legalitas masukan pengguna dan pastikan konten masukan hanya berisi data legal. Inspeksi data harus dilakukan pada sisi klien dan server - validasi sisi server dilakukan untuk mengkompensasi rapuhnya keamanan mekanisme validasi sisi klien.
Di sisi klien, sangat mungkin bagi penyerang untuk mendapatkan kode sumber halaman web, memodifikasi skrip yang memverifikasi legalitas (atau menghapus skrip secara langsung), dan kemudian mengirimkan konten ilegal ke server melalui formulir yang dimodifikasi. Oleh karena itu, satu-satunya cara untuk memastikan bahwa operasi verifikasi benar-benar telah dilakukan adalah dengan melakukan verifikasi di sisi server juga. Anda dapat menggunakan banyak objek validasi bawaan, seperti RegularExpressionValidator, yang secara otomatis dapat menghasilkan skrip sisi klien untuk validasi, dan tentu saja Anda juga dapat memasukkan panggilan metode sisi server. Jika Anda tidak dapat menemukan objek validasi siap pakai, Anda dapat membuatnya sendiri melalui CustomValidator.
⑸ Enkripsi dan simpan nama login pengguna, kata sandi, dan data lainnya. Mengenkripsi data yang dimasukkan oleh pengguna dan kemudian membandingkannya dengan data yang disimpan dalam database sama dengan "mensterilkan" data yang dimasukkan oleh pengguna tidak lagi memiliki arti khusus bagi database, sehingga Mencegah penyerang dari menyuntikkan perintah SQL. Kelas System.Web.Security.FormsAuthentication memiliki HashPasswordForStoringInConfigFile, yang sangat cocok untuk membersihkan data masukan.
⑹ Periksa jumlah catatan yang dikembalikan oleh kueri yang mengekstraksi data. Jika program hanya memerlukan satu record untuk dikembalikan, namun record sebenarnya yang dikembalikan lebih dari satu baris, maka akan dianggap sebagai kesalahan.