1. Apa itu injeksi SQL? Yang disebut injeksi SQL adalah memasukkan perintah SQL ke dalam formulir formulir untuk mengirimkan atau memasukkan string kueri dari nama domain atau permintaan halaman, dan akhirnya mengelabui server untuk menjalankan beberapa perintah SQL berbahaya. Dengan mengirimkan parameter untuk membuat pernyataan SQL yang cerdas, Anda dapat berhasil mendapatkan data yang diinginkan.
2. SQL jenis injeksi Secara khusus, injeksi SQL dapat dibagi menjadi lima kategori, yaitu: injeksi angka, injeksi karakter, injeksi pencarian (seperti), dalam injeksi, dan injeksi koneksi kalimat. Dari sudut pandang aplikasi, perhatian khusus harus diberikan pada injeksi SQL dalam IP, pencarian, penghapusan batch, dan transfer dari database ke database.
3. Cara menyuntikkan
Mari kita lihat contoh tipikal
SqlCommand cmd = new SqlCommand("SELECT * FROM PE_USERS WHERE UserName = '" 2+ UserName + "' AND UserPassword = '" + Kata Sandi + "'", conn); Karena tidak ada validasi untuk UserName dan PassWord, jika UserName="admin' ATAU 1=1--" Pernyataan SQL yang dieksekusi menjadi:
PILIH * DARI PE_USERS DI MANA UserName='admin' ATAU 1=1—' DAN UserPassword='' Ini menghasilkan injeksi SQL, dan kondisinya selalu benar, sehingga Anda dapat berhasil masuk tanpa kata sandi.
4. Cara mencegah injeksi SQL
1. Filter atau konversi string yang mencurigakan
Injeksi SQL dicegah dengan menulis fungsi yang memfilter atau mengonversi string berbahaya, lalu menggunakan GLOBAL.ASAX atau menulis ulang instans konteks
Berikut contohnya
bool statis publik SqlFilter2 (string InText) 2 { 3 string word="and|exec|insert|select|delete|update|chr|mid|master|or|truncate|char|declare|join"; 4 jika(InText==null) 5 mengembalikan palsu; 6 foreach(string i dalam word. Pisah('|')) 7 { 8 if((InText.ToLower(). IndeksDari(i+" ")>-1)|| (InText.ToLower(). IndeksDari(" "+i)>-1)) 9 { 10 mengembalikan true; 11 } 12 } 13 mengembalikan palsu; 14 }
2. Global.asax
dilindungi void Application_BeginRequest(Pengirim objek, EventArgs e) 2 { 3 // Melintasi parameter Post, kecuali untuk domain tersembunyi 4 foreach(string i dalam ini. Permintaan.Formulir) 5 { 6 jika(i=="__VIEWSTATE")lanjutkan; 7 this.goErr(this. permintaan.formulir.kepadaString()); 8 } 9 // Melintasi parameter Get. 10 foreach(string i dalam ini. Permintaan.QueryString) 11 { 12 this.goErr(this. permintaan.kueryaString.ToString()); 13 } 14 } pribadi void goErr(string tm) 2 { 3 jika(WLCW. Extend.CValidity.SqlFilter2(tm)) 4 ini. Tanggapan.akhir() 5 } Kelebihan: Aspek ini digunakan oleh sebagian besar pemrogram pemula untuk mencegah injeksi SQL, dan tampaknya bekerja dengan baik untuk mencegah injeksi dalam banyak cas.
Kekurangan: 1. Ini akan menyaring beberapa karakter yang awalnya tidak digunakan untuk injeksi, menyebabkan masalah yang tidak terduga. Misalnya, jika nama anggota forum berisi karakter yang sama dengan karakter yang difilter, itu akan menyebabkan beberapa masalah dan masalah yang tidak terduga.
2. Penyaringan atau konversi diperlukan setiap saat, yang mengurangi efisiensi program
2. Gunakan prosedur tersimpan untuk kueri parametrik
Tujuan utama injeksi SQL adalah untuk mengeksekusi perintah berbahaya dalam database dengan mengirimkan kode SQL berbahaya. Oleh karena itu, selama perintah SQL diproses sebelum eksekusi, injeksi SQL dapat dicegah secara efektif. Kueri berparameter dapat secara efektif mencegah injeksi SQL.
Contoh
const string strSql = "PILIH * DARI [PE_Users] DI MANA UserName = @UserName"; Parameter parms = Parameter baru("@UserName", DbType.String, userName); Ada parameter @UserName di atas, menggunakan objek Prarmeter, di mana parameter ditambahkan ke objek Command, Ini memberi Anda kueri berparameter. Seperti yang dijelaskan di atas, ADO.NET mengirimkan pernyataan SQL berikut ke SQL Server:
Exec sp_executesql N 'pilih * dari [pe_users] di mana username=@username ',N '@username nvarchar(20) ',@username=N 'nama' SQL Server menggantikan @username dengan string "nama" sebelum menjalankan kueri. Misalkan Anda memiliki input berikut:
'Union pilih @@version,null,null— Pernyataan SQL yang dihasilkan terlihat seperti ini:
Exec sp_executesql N 'pilih * dari [pe_users] di mana username=@username ',N '@username nvarchar(20) ',@username=N ''' union select @@version,null,null--' Anda dapat melihat bahwa ADO.NET lolos dari input.
- public SqlParameter Add(string parameterName, SqlDbType sqlDbType, int size);
Salin kode
DbTye atau SqlDbType dapat berupa berbagai tipe data. Anda dapat memilih berdasarkan jenis data Anda. Di beberapa tempat, ini juga dapat digunakan untuk menentukan panjang parameter: ukuran int. Ini juga secara efektif mencegah luapan database dan catatan SQL Kemungkinan masuk. Kelebihan: Secara efektif mencegah injeksi SQL. Kekurangan: Beberapa tempat tidak dapat diterapkan, seperti di.
3. Daftar putih
Deskripsi: Beberapa rentang parameter yang diketahui dapat ditangani dalam bentuk daftar putih, yang dapat mencegah injeksi dan kueri SQL Salah, misalnya: urutkan berdasarkan + nama kolom, ketika nama kolom diteruskan dalam bentuk parameter, daftar putih dapat dirumuskan untuk menilai parameter terlebih dahulu apakah nomor tersebut ada dalam daftar putih, lalu kueri, jika tidak, nomor tersebut akan diproses secara tidak benar. Keuntungan: aman dan andal Kekurangan: Berbagai aplikasi kecil |