about sql injection

Senin, 12 Juli 2010

ini saya dapat dari website microsoft,,dengan menerjemahkannya di mbah google.banyak orang yang belum mengenal sql injeksi bagi kalangan it,apalagi yang tidak bergelut di dunia it.di sini sayainjeksi adalah serangan kode jahat yang dimasukkan ke dalam string yang kemudian diteruskan ke sebuah contoh dari SQL Server untuk parsing dan eksekusi. Setiap prosedur bahwa pernyataan SQL konstruksi harus ditinjau ulang untuk kerentanan injeksi karena SQL Server akan menjalankan semua pertanyaan sintaktis yang valid yang diterima. Bahkan data parameter dapat dimanipulasi oleh penyerang terampil dan ditentukan.

Bentuk injeksi SQL utama terdiri dari penyisipan langsung kode ke variabel user-masukan yang concatenated dengan perintah SQL dan dieksekusi. Serangan tidak langsung menyuntikkan kode berbahaya ke dalam string yang ditakdirkan untuk penyimpanan dalam sebuah tabel atau sebagai metadata. Ketika string disimpan selanjutnya concatenated ke perintah SQL dinamis, kode jahat dijalankan.

Proses injeksi bekerja dengan prematur terminating string teks dan menambahkan perintah baru. Karena perintah dimasukkan mungkin ditambahkan string tambahan untuk itu sebelum dijalankan, penjahat yang mengakhiri string disuntik dengan tanda komentar "--". teks berikutnya akan diabaikan pada waktu eksekusi.

Naskah berikut ini menunjukkan sebuah injeksi SQL sederhana. Script membangun sebuah query SQL oleh concatenating string keras-kode bersama-sama dengan string yang dimasukkan oleh pengguna:
copy saja|:
var Shipcity;
ShipCity = Request.form ("ShipCity");
var sql = "select * from OrdersTable where ShipCity = '" + ShipCity + "'";


SELECT * FROM WHERE OrdersTable ShipCity Redmond = ''

Namun, menganggap bahwa pengguna memasukkan hal berikut:

Redmond'; drop table OrdersTable--

Dalam hal ini, pertanyaan berikut ini dirakit oleh skrip:

SELECT * FROM WHERE OrdersTable ShipCity = '; Redmond tabel' drop OrdersTable - '

The titik koma (;) menunjukkan akhir satu permintaan dan awal lagi. Itu tanda hubung ganda (-) menunjukkan bahwa sisa baris saat ini adalah sebuah komentar dan harus diabaikan. Jika kode diubah secara sintaktis adalah benar, maka akan dijalankan oleh server. Ketika proses SQL Server pernyataan ini, SQL Server pertama akan memilih semua catatan dalam OrdersTable mana ShipCity adalah Redmond. Kemudian, akan drop SQL Server OrdersTable.

Selama kode SQL disuntikkan secara sintaktis adalah benar, gangguan tidak dapat dideteksi pemrograman. Oleh karena itu, Anda harus memvalidasi semua input pengguna dan hati-hati memeriksa kode yang menjalankan perintah SQL dibangun pada server yang Anda gunakan. Coding praktik terbaik dijelaskan pada bagian berikutnya dalam topik ini.
Validasi Input Semua

Selalu memvalidasi input pengguna dengan menguji jenis, panjang, format, dan jangkauan. Ketika Anda melaksanakan tindakan pencegahan terhadap masukan berbahaya, mempertimbangkan arsitektur dan skenario penyebaran aplikasi Anda. Ingat bahwa program yang dirancang untuk berjalan di lingkungan yang aman dapat disalin ke lingkungan tidak aman. Saran-saran berikut ini harus dipertimbangkan praktek-praktek terbaik:





* Tidak membuat asumsi tentang ukuran, jenis, atau isi dari data yang diterima oleh aplikasi Anda. Misalnya, Anda harus membuat evaluasi berikut:


1. Bagaimana aplikasi Anda bersikap jika pengguna bersalah atau berbahaya memasuki MPEG 10-megabyte file mana aplikasi Anda mengharapkan kode pos?
2. Bagaimana aplikasi Anda bersikap jika pernyataan DROP TABLE tertanam di dalam kolom teks?


* Uji ukuran dan tipe data input dan menegakkan sesuai batas. Hal ini dapat membantu mencegah buffer overruns disengaja.
* Uji isi variabel string dan hanya menerima nilai-nilai yang diharapkan. Tolak entri yang berisi data biner, urutan melarikan diri, dan karakter komentar. Hal ini dapat membantu mencegah injeksi script dan dapat melindungi terhadap beberapa eksploitasi buffer overrun.
* Ketika Anda bekerja dengan dokumen XML, memvalidasi semua data terhadap skema-nya seperti yang dimasukkan.
* Pernah membangun Transact-SQL laporan langsung dari input pengguna.
* Gunakan prosedur yang tersimpan untuk memvalidasi input pengguna.
*
* Dalam lingkungan multitiered, semua data harus divalidasi sebelum masuk ke zona dipercaya. Data yang tidak lulus proses validasi harus ditolak dan kesalahan harus dikembalikan ke tingkat sebelumnya.
* Menerapkan beberapa lapisan validasi. Anda mengambil tindakan pencegahan terhadap pengguna santai mungkin berbahaya tidak efektif terhadap penyerang ditentukan. Praktek yang lebih baik adalah memvalidasi masukan pada antarmuka pengguna dan pada semua titik berikutnya di mana ia menyeberangi batas kepercayaan.
* Sebagai contoh, data validasi dalam aplikasi client-side dapat mencegah injeksi script sederhana. Namun, jika tingkat berikutnya mengasumsikan bahwa input telah divalidasi, setiap pengguna berbahaya yang bisa bypass klien dapat memiliki akses tidak terbatas terhadap sistem.
*
* Masukan pengguna tidak pernah menyatukan yang tidak divalidasi. Rangkaian String adalah titik utama masuk untuk injeksi script.
*
* Jangan menerima string berikut dalam bidang yang nama file bisa dibangun: AUX, CLOCK $, COM1 melalui COM8, CON, CONFIG $, LPT1 melalui LPT8, Nul, dan PRN.


Bila Anda dapat, menolak input yang berisi karakter berikut ini.

Input karakter


Makna dalam Transact-SQL

; =Permintaan pembatas.

' =Karakter data string pemisah.

- =Komentar pembatas.

/ * ... * / =Komentar pembatas. Teks antara / * dan * / tidak dievaluasi oleh server.

xp_


Digunakan pada awal nama prosedur yang tersimpan katalog-diperpanjang, seperti xp_cmdshell.
Gunakan SQL Parameters Jenis Aman

Koleksi Parameter di SQL Server menyediakan memeriksa jenis dan validasi panjang. Jika Anda menggunakan koleksi Parameter, masukan diperlakukan sebagai nilai literal bukan sebagai kode dieksekusi. Sebuah keuntungan tambahan dari menggunakan koleksi Parameter adalah bahwa Anda dapat menerapkan jenis dan cek panjang. Nilai di luar jangkauan akan memicu pengecualian. Fragmen kode berikut menunjukkan dengan menggunakan koleksi Parameter:

SqlDataAdapter myCommand = new SqlDataAdapter("AuthorLogin", conn);
myCommand.SelectCommand.CommandType = CommandType.StoredProcedure;
SqlParameter parm = myCommand.SelectCommand.Parameters.Add("@au_id",
SqlDbType.VarChar, 11);


Dalam contoh ini,
parameter au_id @ diperlakukan sebagai nilai literal bukan sebagai kode
dieksekusi. Nilai ini diperiksa jenis
dan panjang. Jika nilai @ au_id tidak
sesuai dengan jenis tertentu dan kendala panjang, pengecualian akan
dilempar.Gunakan parameter Input
dengan Stored Prosedur

Prosedur yang tersimpan
dapat menerima injeksi SQL jika mereka menggunakan tanpa filter masukan.
Sebagai contoh, kode
berikut ini rentan:

SqlDataAdapter myCommand =
new SqlDataAdapter("LoginStoredProcedure '" +
Login.Text + "'", conn);




Jika Anda menggunakan
prosedur yang tersimpan, Anda harus menggunakan parameter sebagai
masukan mereka.

Gunakan Koleksi Parameter dengan Dynamic SQL

Jika Anda tidak dapat
menggunakan prosedur yang tersimpan, Anda masih dapat menggunakan
parameter, seperti ditunjukkan dalam contoh kode berikut:

SqlDataAdapter myCommand = new SqlDataAdapter(
"SELECT au_lname, au_fname FROM Authors WHERE au_id = @au_id", conn);
SQLParameter parm = myCommand.SelectCommand.Parameters.Add("@au_id",
SqlDbType.VarChar, 11);

Parm.Value = Login.Text;


Penyaringan Input


Penyaringan masukan juga mungkin dapat membantu dalam melindungi terhadap injeksi SQL dengan
menghapus karakter melarikan diri. Namun, karena banyaknya
karakter yang dapat menimbulkan masalah, ini bukan pertahanan dapat
diandalkan. Contoh berikut pencarian
untuk pembatas string karakter.


private string SafeSqlLiteral(string inputSQL)
{
return inputSQL.Replace("'", "''");
}



SEPERTI Klausul



Catatan bahwa jika Anda
menggunakan klausa LIKE, karakter wildcard masih harus escape:

Salinan



s = s.Replace ("[",
"[[]");

s = s.Replace ("%",
"[%]");

s = s.Replace ("_",
"[_]");



Meninjau Kode untuk SQL
Injection



Anda harus meninjau semua
kode yang panggilan Execute, EXEC, atau sp_executesql. Anda dapat menggunakan
query mirip dengan berikut ini untuk membantu Anda mengidentifikasi
prosedur yang berisi laporan. Ini cek query untuk 1, 2,
3, atau 4 spasi setelah kata-kata Jalankan atau EXEC.



Object_Name SELECT (id)
syscomments DARI



WHERE UPPER (teks)% LIKE
'Execute (%'



OR UPPER (teks)% LIKE
'Execute (%'



OR UPPER (teks)% LIKE
'Execute (%'



OR UPPER (teks)% LIKE
'Execute (%'



OR UPPER (teks)% LIKE
'EXEC (%'



OR UPPER (teks)% LIKE
'EXEC (%'



ATAU UPPER (teks)% LIKE
'EXEC (%'



OR UPPER (teks)% LIKE
'EXEC (%'



OR UPPER (teks)% LIKE '%
SP_EXECUTESQL'

Parameter pembungkus
dengan QUOTENAME () dan REPLACE ()



Dalam setiap prosedur
yang dipilih disimpan, pastikan bahwa semua variabel yang digunakan
dalam Transact-SQL dinamis ditangani dengan benar. Data yang berasal dari
parameter masukan dari prosedur yang disimpan atau dibaca dari tabel
harus dibungkus QUOTENAME () atau REPLACE (). Ingatlah bahwa nilai @
variabel yang dilewatkan ke QUOTENAME () adalah sysname, dan memiliki
panjang maksimum 128 karakter.



@ Variabel





Fitur pembungkus



Nama sebuah securable





QUOTENAME (@ variabel)



String ≤ 128 karakter





QUOTENAME (@
variabel,'''')



String> 128 karakter





REPLACE (@ variabel
,'''','''''')



Bila Anda menggunakan
teknik ini, pernyataan SET dapat direvisi sebagai berikut:



- Sebelum:



SET @ temp = N'select *
dari penulis di mana au_lname ='''



+ @ Au_lname + N''''



- Setelah:



SET @ temp = N'select *
dari penulis di mana au_lname ='''



+ REPLACE (@ au_lname
,'''','''''') + N''''

Injeksi Enabled oleh Data
Pemotongan



Setiap Transact-SQL
dinamis yang diberikan ke variabel akan dipotong jika lebih besar dari
buffer dialokasikan untuk variabel tersebut. Seorang penyerang yang
mampu memaksa pemotongan pernyataan yang lewat tiba-tiba tali panjang
dengan prosedur yang tersimpan dapat memanipulasi hasilnya. Misalnya, prosedur yang
tersimpan yang dibuat oleh script berikut ini rentan terhadap injeksi
diaktifkan oleh pemotongan.



CREATE PROSEDUR
sp_MySetPassword



@ Loginname sysname,



@ Tua sysname,



@ Baru sysname



AS



- Deklarasi variabel.



- Perhatikan bahwa buffer
di sini adalah hanya 200 karakter.



MENYATAKAN @ perintah
varchar (200)



- Membangun dinamis
Transact-SQL.



- Dalam pernyataan
berikut ini, kita perlu total 154 karakter



- Untuk mengatur password
'sa'.



- 26 untuk pernyataan
UPDATE, 16 untuk WHERE klausa, 4 untuk 'sa', dan 2 untuk



- Tanda kutip dikelilingi
oleh QUOTENAME (@ loginname):



- 200-26 - 16-4 - 2 =
154.



- Tapi karena @ baru ini
dideklarasikan sebagai sebuah sysname, variabel ini hanya dapat terus



- 128 karakter.



- Kita dapat mengatasi
ini dengan melewatkan beberapa tanda kutip tunggal di @ baru.



SET @ command = 'Pengguna
update set password =' + QUOTENAME (@ baru, ''''') + loginname dimana
username + =' QUOTENAME (@,'''') + 'DAN password =' + QUOTENAME (@ lama ,'''')



- Jalankan perintah.



EXEC (@ command)



GO



Dengan melewati 154
karakter menjadi 128 karakter buffer, penyerang bisa mengatur sandi baru
untuk sa tanpa mengetahui password lama.



sa EXEC sp_MySetPassword
'', 'dummy',
'123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012''''''''''''''''''''''''''''''''''''''
'''''''''''''



Untuk alasan ini, Anda
harus menggunakan buffer besar untuk sebuah variabel perintah atau
langsung jalankan Transact-SQL dinamis dalam pernyataan Execute.

Pemotongan Ketika
QUOTENAME (@ variabel,'''') dan REPLACE () Apakah Digunakan



String yang dikembalikan
oleh QUOTENAME () dan REPLACE () akan diam-diam dipotong jika mereka
melebihi ruang yang dialokasikan. Prosedur yang tersimpan
yang dibuat dalam contoh berikut menunjukkan apa yang bisa terjadi.



CREATE PROSEDUR
sp_MySetPassword



@ Loginname sysname,



@ Tua sysname,



@ Baru sysname



AS



- Deklarasi variabel.



MENYATAKAN @ login
sysname



MENYATAKAN @ Newpassword
sysname



MENYATAKAN @ oldpassword
sysname



MENYATAKAN @ perintah
varchar (2000)



- Dalam laporan berikut,
data yang disimpan di variabel temp



- Akan dipotong karena
ukuran penyangga @ login, @ oldpassword,



- Dan @ Newpassword hanya
128 karakter, tetapi QUOTENAME () bisa kembali



- Hingga 258 karakter.



@ SET login = QUOTENAME
(@ loginname,'''')



SET @ oldpassword =
QUOTENAME (@ tua,'''')



SET @ Newpassword =
QUOTENAME (@ baru,'''')



- Membangun dinamis
Transact-SQL.



- Jika baru @ berisi 128
karakter, maka akan Newpassword @ '123 ... n



- Di mana n adalah 127
karakter.



- Karena string
dikembalikan oleh QUOTENAME () akan dipotong,



- Itu dapat dibuat agar
terlihat seperti pernyataan berikut:



- UPDATE Pengguna SET
password = '1234. . [127] WHERE username. =
'- Hal lain di sini



SET @ command = 'Pengguna
UPDATE set password =' + @ Newpassword



+ "Dimana username + = '@
login +' DAN password = '+ @ oldpassword;



- Jalankan perintah.



EXEC (@ command)



GO



Oleh karena itu,
pernyataan berikut akan menetapkan password semua pengguna dalam nilai
yang disahkan dalam kode sebelumnya.



EXEC sp_MyProc'--',
'dummy',
'12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
'



Anda bisa memaksa
pemotongan string dengan melebihi ruang buffer yang dialokasikan bila
Anda menggunakan REPLACE (). Prosedur yang tersimpan
yang dibuat dalam contoh berikut menunjukkan apa yang bisa terjadi.



CREATE PROSEDUR
sp_MySetPassword



@ Loginname sysname,



@ Tua sysname,



@ Baru sysname



AS



- Deklarasi variabel.



MENYATAKAN @ login
sysname



MENYATAKAN @ Newpassword
sysname



MENYATAKAN @ oldpassword
sysname



MENYATAKAN perintah
varchar @ (2000)



- Dalam laporan berikut,
data akan dipotong karena



- Yang dialokasikan untuk
buffer @ login, @ oldpassword dan @ Newpassword



- Dapat menyimpan hanya
128 karakter, tetapi QUOTENAME () bisa kembali



- Hingga 258 karakter.



SET @ login = REPLACE (@
loginname,'''','''''')



SET @ oldpassword =
REPLACE (@ tua,'''','''''')



SET @ Newpassword =
REPLACE (@ baru,'''','''''')



- Membangun dinamis
Transact-SQL.



- Jika baru @ berisi 128
karakter, @ Newpassword akan '123 ... n



- Di mana n adalah 127
karakter.



- Karena string
dikembalikan oleh QUOTENAME () akan dipotong, itu



- Dapat dibuat agar
terlihat seperti pernyataan berikut:



- UPDATE Pengguna SET
password = '1234 ... [127] WHERE username = '- hal-hal lain di sini



SET @ command = 'Pengguna
update password + =''' @ Newpassword''+ 'dimana username ='''



+ @ Login +'''password
DAN =''' + @ oldpassword +'''';



- Jalankan perintah.



EXEC (@ command)



GO



Seperti QUOTENAME (),
pemotongan string oleh REPLACE () dapat dihindari dengan menyatakan
variabel temporer yang cukup besar untuk semua kasus. Bila memungkinkan, Anda
harus menghubungi QUOTENAME () atau REPLACE () secara langsung di dalam
Transact-SQL dinamis. Jika tidak, Anda dapat
menghitung ukuran buffer yang dibutuhkan sebagai berikut. Untuk @ outbuffer =
QUOTENAME (@ input), ukuran @ outbuffer harus 2 * (len (@ input) 1). Bila Anda menggunakan
REPLACE () dan tanda kutip dua kali lipat, seperti pada contoh
sebelumnya, sebuah penyangga 2 * input (len @) sudah cukup.



Perhitungan berikut
mencakup semua kasus:



0, required buffer size =" onmouseover="this.style.backgroundColor='#ebeff9'" onmouseout="this.style.backgroundColor='#fff'">Sementara len (@
find_string)> 0, ukuran buffer yang dibutuhkan =



bulat (len (@ input) /
len (@ find_string), 0) * len (@ new_string)



+ (Len (@ input) len% (@
find_string))

Pemotongan Ketika
QUOTENAME (@ variabel, ']') Apakah Digunakan



Pemotongan dapat terjadi
ketika nama SQL Server securable dilewatkan laporan yang menggunakan
formulir QUOTENAME (@ variabel,']'). Contoh berikut ini
menunjukkan ini.



CREATE PROSEDUR sp_MyProc



@ Schemaname sysname,



@ Tablename sysname,



AS



- Deklarasi sebuah
variabel sebagai sysname. Variabel ini akan 128
karakter.



- Tapi objectname @
sebenarnya harus memungkinkan untuk 2 * 1 258 karakter.



MENYATAKAN @ objectname
sysname



SET @ objectname =
QUOTENAME (@ schemaname )+'.'+ QUOTENAME (@ tablename)



- Apakah beberapa
operasi.



GO



Ketika Anda concatenating
nilai sysname jenis, Anda harus menggunakan variabel sementara cukup
besar untuk menampung 128 karakter maksimum per nilainya. Jika memungkinkan,
QUOTENAME panggilan () secara langsung di dalam Transact-SQL dinamis. Jika tidak, Anda dapat
menghitung ukuran buffer yang dibutuhkan seperti yang dijelaskan pada
bagian sebelumnya.

pendapat: 
0 komentar

Poskan Komentar

look ! bugs my blog

visitors