Pada artikel sebelumnya kita sudah membahas tentang inti dari kerentanan serangan injeksi SQL yang disebabkan oleh coding yang tidak tepat oleh programmer. Sekarang kita akan melanjutkan pembahasan tentang cara coding yang benar agar tidak diserang oleh SQL injection masalah Mari kita lihat sepotong kode terlebih dahulu:
Copy kode kodenya sebagai berikut:
redupkan sql_injdata,SQL_inj,SQL_Get,SQL_Data,Sql_Post
SQL_injdata = '|dan|exec|masukkan|pilih|hapus|perbarui|hitungan|*|%|chr|mid|master|truncate|char|deklarasikan
SQL_inj = terbagi(SQL_Injdata,|)
Jika Permintaan.QueryString<> Lalu
Untuk Setiap SQL_Dapatkan Di Permintaan.QueryString
Untuk SQL_Data=0 Ke Ubound(SQL_inj)
jika instr(Request.QueryString(SQL_Get),Sql_Inj(Sql_DATA))>0 Lalu
Response.Write <Script Language=javascript>alert('SQL sistem anti-injeksi meminta, mohon jangan mencoba menginjeksi lagi!'); history.back(-1)</Script>
Respon.akhir
berakhir jika
Berikutnya
Berikutnya
Akhiri Jika
Jika Permintaan.Formulir<> Lalu
Untuk Setiap Sql_Post Di Request.Form
Untuk SQL_Data=0 Ke Ubound(SQL_inj)
jika instr(Request.Form(Sql_Post),Sql_Inj(Sql_DATA))>0 Lalu
Response.Write <Script Language=javascript>alert('SQL sistem anti-injeksi meminta, mohon jangan mencoba menginjeksi lagi!'); history.back(-1)</Script>
Respon.akhir
berakhir jika
Berikutnya
Berikutnya
berakhir jika
Ini adalah bagian dari kode anti-injeksi ASP yang sangat populer di Internet. Idenya adalah untuk memeriksa data yang dikirimkan dengan metode Post dan metode Dapatkan, dan untuk mencegah injeksi SQL dengan memfilter karakter sensitif seperti Sisipkan, Perbarui, Dan. , dll. Secara teori, jika kami memfilter karakter yang cukup, kami pasti dapat menjamin bahwa kami tidak akan diserang oleh injeksi SQL, tapi harap berhati-hati. Baca kode ini dan perhatikan cara penilaiannya. Ini dinilai melalui fungsi instr Artinya, jika saya ingin memfilter karakter dan, bukan hanya kata And yang disaring, tetapi juga semua kata. mengandung dan. Semua kata dengan kombinasi karakter berikut telah disaring, seperti pulau, daratan, tangan... Jika karakter ini disaring, apakah masih ada yang mau menggunakannya? Oleh karena itu, metode memfilter karakter sensitif ini tidak ada artinya sama sekali. Yang mengejutkan saya adalah bahwa sampah seperti itu sebenarnya diposting di Internet sebagai karya klasik.
Beberapa orang mengatakan bahwa serangan injeksi SQL disebabkan oleh penyambungan string kueri SQL, jadi menggunakan prosedur tersimpan tanpa penyambungan string kueri SQL dapat melindungi Anda dari serangan injeksi SQL. Belum tentu, mari kita lihat contoh serangan injeksi prosedur tersimpan.
Kode prosedur tersimpan dt_GetNews adalah sebagai berikut:
BUAT PROSEDUR dt_GetNews
@ tipe berita ke dalam
SEBAGAI
pilih * dari berita di mana newstype=@newstype
PERGI
Kode panggilan:
<%
koneksi redup
setel adoconnection=server.buat objek(adodb.koneksi)
'.........Kode yang relevan untuk membuat koneksi database dihilangkan di sini
adoconnection.execute exec dt_GetNews +permintaan(tipe berita)
adoconnection.close
%>
Jika nilai request(newstype) sama dengan 1, hasil operasinya adalah mengembalikan semua record dengan field newstype di tabel berita menjadi 1. Namun, jika nilai request(newstype) adalah 1; , hasil yang dikembalikan adalah tabel berita dihapus.
Dapat dilihat dari contoh ini bahwa bahkan menggunakan prosedur tersimpan akan tetap diserang. Selain itu, pilih * dari berita di mana newstype=@newstype tidak disambung, sehingga tidak ada hubungan yang tidak dapat dihindari antara penyambungan string kueri SQL dan serangan injeksi SQL. prosedur tersimpan mungkin tidak dapat melindungi terhadap serangan injeksi.
Jadi bagaimana Anda menulisnya tanpa diserang oleh injeksi SQL? Di bawah ini saya akan memperkenalkan metode pamungkas, terus terang, ini sangat sederhana dan primitif, yaitu verifikasi tipe data dan penggantian kutipan tunggal. Baik itu Oracle, Sql Server, mySql, Access, atau database relasional lainnya, tipe bidang secara kasar dapat dibagi menjadi dua kategori: tipe numerik (seperti int, float, dll.) dan tipe karakter (seperti char, varchar, dll. ). Pernyataan SQL terkait sedikit berbeda bergantung pada jenis bidang, seperti:
Bidang tipe berita di Pilih * dari berita dengan tipe berita=1 harus berupa bidang numerik.
pilih * dari berita dimana newstype='berita sosial' bidang newstype harus berupa bidang karakter.
Untuk field numerik, yang harus kita lakukan adalah memeriksa tipe data parameternya. Misalnya, ketika kita membuat pernyataan query menggunakan select * from news dimana newstype=+v_newstype, kita harus memeriksa tipe data dari variabel v_newstype setidaknya Itu harus berupa angka, yang bisa berupa bilangan bulat atau angka floating point. Jika pemeriksaan seperti itu dilakukan, select * from news di mana newstype=+v_newstype tidak akan pernah membuat sesuatu yang mirip dengan select * from news di mana newstype=1. ;menjatuhkan Pernyataan seperti berita meja. Alasan mengapa ASP lebih rentan terhadap serangan dibandingkan ASP.Net, JSP, dll adalah karena variabel dalam ASP tidak perlu dideklarasikan dan jenis variabelnya tidak jelas.
Untuk field karakter yang harus kita lakukan adalah mengolah tanda kutip tunggal ('). Cara pengolahannya adalah dengan mengganti satu tanda kutip tunggal dengan dua tanda kutip tunggal (''). Ketika newstype='+v_newstype+' digunakan untuk membuat pernyataan kueri, tanda kutip tunggal di v_newstype harus diganti dengan dua tanda kutip tunggal, karena dalam SQL bagian yang diapit oleh dua tanda kutip tunggal mewakili sebuah string, dan dua tanda kutip tunggal yang berurutan. kutipan mewakili karakter kutipan tunggal. Setelah pemrosesan tersebut, kita akan melihat metode konstruksi pilih * dari berita di mana newstype='+v_newstype+'.
Berita sosial'; berita drop table--
Setelah mengganti satu tanda kutip menjadi dua tanda kutip tunggal, nilai v_newstype menjadi:
Berita sosial''; berita drop table--
Pernyataan SQL yang dibangun menjadi:
pilih * dari berita di mana newstype='berita sosial'';letakkan berita tabel—'
Hasil kuerinya adalah mengembalikan rekaman yang nilai bidang tipe beritanya di tabel berita adalah berita sosial'; berita tabel drop--, tanpa menyebabkan tabel berita terhapus seperti sebelumnya.
Selain itu, yang perlu diproses bukan hanya pernyataan Select saja, antara lain Insert, Update, Delete, Exec, dll, Anda bisa melihat cara injeksi berikut ini:
Dalam struktur masukkan ke dalam berita(judul) nilai('+v_judul+'),
Ketika v_title=123';jatuhkan berita tabel--';
Saat update news set />when v_title=123'-- atau v_id=1;drop table news--, jadi bukan hanya pernyataan Select yang bermasalah, tapi pernyataan lain mungkin bermasalah, jangan hanya fokus pada Select
Singkatnya, setelah memverifikasi tipe data dan memproses karakter kutipan tunggal, meskipun ia memiliki semua kemampuan, ia tidak akan bisa terbang keluar dari telapak tangan Tathagata saya.