Haruskah kita masih menggunakan QUOTENAME untuk melindungi dari serangan injeksi?

9

Saya melihat prosedur lama yang tersimpan hari ini dan memerhatikan itu menggunakan quotenameparameter input. Setelah melakukan penggalian untuk mencari tahu apa yang dilakukannya, saya menemukan situs ini . Saya sekarang mengerti apa yang dilakukannya dan bagaimana menggunakannya tetapi situs tersebut mengatakan itu digunakan sebagai mitigasi dari serangan SQL Injection. Ketika saya dulu mengembangkan aplikasi yang secara langsung menanyakan database, menggunakan asp.net, saya akan menggunakan parameter ADO.Net untuk mengirimkan input pengguna sebagai nilai literal dan tidak pernah benar-benar khawatir tentang melindunginya dalam prosedur tersimpan saya.

Saya sekarang menulis prosedur tersimpan yang akan digunakan oleh aplikasi yang tidak saya tulis jadi saya perlu mencoba dan melindungi dari serangan injeksi di tingkat prosedur, adalah quotenamecara terbaik untuk melakukan ini atau apakah ada fungsi yang lebih baru / lebih baik metode?

Kode yang memberi saya pola pikir ini ( @parm1adalah parameter input pengguna):

'SELECT project [Project], project_desc [Description], 
        customer [Customer], cpnyid [Company]
FROM PJPROJ (nolock)
where project like ' + quotename(@parm1,'''') + '
Matius Verstraete
sumber

Jawaban:

17

Ya, banyak hal yang tidak banyak berubah di area ini, Anda harus menggunakan quotenamenama objek server SQL apa pun yang digunakan dalam SQL dinamis (terutama jika mereka diberikan secara eksternal ke kode Anda). Selain mitigasi injeksi SQL, ini juga berarti kode Anda akan berfungsi dengan benar untuk nama pengidentifikasi non standar.

Fungsi ini hanya sesuai untuk nama objek (misalnya tabel, kolom, nama database).

Anda harus mencoba dan membuat parameter segala sesuatu yang lain dan menggunakan sp_executesql, memasukkan parameter daripada menggabungkannya ke dalam string kueri.

Artikel definitif tentang topik ini masih The Curse and Blessings of Dynamic SQL


Edit. Sekarang Anda telah menyediakan kode yang saya lihat melewati parameter kedua 'untuk menambahkan tanda kutip luar dan menghindari tanda kutip tunggal dengan menggandakannya sebelum menyuntikkannya ke dalam string. Ini bukan penggunaan nama samaran yang baik. Ini akan gagal (mengembalikan nol) jika string lebih besar dari 128 karakter.

Selain itu Masih dapat meninggalkan kemungkinan injeksi SQL jika string berisi U + 02BC bukannya tanda kutip standar dan kemudian string tersebut ditugaskan ke varchar setelah sanitasi (di mana ia dapat secara diam-diam dikonversi menjadi tanda kutip biasa )

Cara yang benar untuk melakukan ini adalah membiarkan parameterisasi kueri. Dan kemudian berikan @parm1nilainya kesys.sp_executesql

DECLARE @Sql NVARCHAR(MAX);

SET @Sql = '
SELECT project      [Project],
       project_desc [Description],
       customer     [Customer],
       cpnyid       [Company]
FROM   PJPROJ (nolock)
WHERE  project LIKE @parm1 
';

EXEC sys.sp_executesql
  @Sql,
  N'@parm1 varchar(100)',
  @parm1 = 'foobar%'; 
Martin Smith
sumber