Enjeksiyon saldırılarına karşı hala QUOTENAME kullanmalı mıyız?


9

Bugün eski bir saklı yordam bakıyordum quotenameve giriş parametreleri üzerinde kullandığını fark ettim . Biraz kazma yaptıktan sonra tam olarak bu siteye rastladım . Şimdi ne yaptığını ve nasıl kullanılacağını anlıyorum, ancak site SQL Enjeksiyon saldırılarının hafifletilmesi olarak kullanıldığını söylüyor. Asp.net kullanarak doğrudan bir veritabanını sorgulayan uygulamalar geliştirmek için kullandığımda, kullanıcı girdisini gerçek bir değer olarak iletmek için ADO.Net parametrelerini kullanırdım ve saklı yordamlarımda koruma konusunda gerçekten endişelenmezdim.

Şimdi yazmadığım uygulamalar tarafından kullanılacak saklı bir yordam yazıyorum, bu yüzden işlem düzeyinde enjeksiyon saldırılarına karşı denemem ve korumam gerekiyor, quotenamebunu yapmanın en iyi yolu veya daha yeni bir işlev var / daha iyi yöntem?

Beni bu düşünce modelinden alan kod ( @parm1bir kullanıcı giriş parametresidir):

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

Yanıtlar:


17

Evet, bu alanda işler çok değişmedi quotename, dinamik SQL'de kullanılan herhangi bir SQL sunucusu nesne adı için kullanmalısınız (özellikle kodunuza harici olarak sağlandıysa). SQL enjeksiyonunu hafifletmenin yanı sıra bu, kodunuzun standart olmayan tanımlayıcı adları için düzgün çalışacağı anlamına gelir.

Bu işlev yalnızca nesne adları (örn. Tablo, sütun, veritabanı adları) için uygundur.

Bunları sp_executesqlsorgu dizesine birleştirmek yerine parametreleri aktararak diğer her şeyi ve parametrelemeyi denemelisiniz .

Bu konudaki kesin makale hala Dinamik SQL'in Laneti ve Bereketleri


Düzenle. Şimdi 'dış tırnak eklemek ve dize enjekte etmeden önce onları iki katına çıkarmak herhangi bir tek tırnak kaçmak için ikinci parametre geçiyor gördüğünüz kodu sağladı . Bu, quotename'in iyi bir kullanımı değildir. Dize 128 karakterden büyükse başarısız olur (null döndürür).

Buna ek olarak, dize standart kesme işareti yerine U + 02BC içeriyorsa ve daha sonra dize, sanitasyondan sonra bir varchar'a atanır ( sessizce düzenli bir kesme işaretine dönüştürülebilir ).

Bunu yapmanın doğru yolu sorguyu parametreli olarak bırakmaktır. Ve sonra @parm1değerisys.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%'; 
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.