Aracılığıyla paylaş


SQL ınjection

SQL ekleme, kötü amaçlı kod örneğine daha sonra geçirilen dizeleri eklenir, saldırının olur. SQL Server Ayrıştırma ve yürütme. Çünkü, ekleme güvenlik açıkları için SQL deyimlerini oluşturur herhangi bir yordamı gözden geçirilmedi SQL Server aldığı tüm sözdizimsel olarak geçerli sorguları çalıştırır. Parametreli hale getirilmiş bile veri nitelikli ve belirlenen bir saldırgan tarafından yönetilebilir.

Birincil SQL ekleme, formun içine SQL komutları ile birleştirilmiş ve yürütülen değişkenleri kullanıcı girişini doğrudan ekleme kodu oluşur.Daha az doğrudan bir saldırı, kötü amaçlı kod bir tabloda veya meta veriler depolama için hedeflenen dizeleri içine injects.Saklı dizeleri daha sonra bir dinamik SQL komutu ile birleştirilmiş, kötü amaçlı kodu yürütülür.

Ekleme işlemi zamanından önce bir metin dizesi sonlandırılıyor ve yeni bir komut ekleme olarak çalışır.Eklenen komut bu yürütülmeden önce kendisine eklenen ek dizeler olabilir, çünkü malefactor denediği dize bir Açıklama işaretiyle sona erdirir ";".Yürütme saat sonraki metni göz ardı edilir.

Aşağıdaki komut dosyasını, basit bir SQL ekleme gösterir.Komut dosyası, sabit kodlanmış dizelerle birlikte kullanıcı tarafından girilen dize içinde birleştirerek bir SQL sorgusu oluşturur:

var Shipcity;
ShipCity = Request.form ("ShipCity");
var sql = "select * from OrdersTable where ShipCity = '" + ShipCity + "'";

Kullanıcı bir şehir adını girmeniz istenir.Filiz girerse Redmond, aşağıdakine benzer bir komut dosyası tarafından birleştirilmiş sorgu:

SELECT * FROM OrdersTable WHERE ShipCity = 'Redmond'

Ancak, kullanıcının aşağıdaki girdiği varsayılmaktadır:

Redmond'; drop table OrdersTable--

Bu durumda, aşağıdaki sorgu komut dosyası tarafından derlenip:

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

Noktalı virgülü (;) bir sorgu sonuna ve başka başlangıcını gösterir.Çift tire (-), Cari satırın kalan bir açıklama ve göz ardı gösterir.Değiştirilmiş kodu doğru değilse, sunucu tarafından yürütülür.Ne zaman SQL Server Bu deyim, işler SQL Server önce tüm kayıtları seçin OrdersTable burada ShipCity olan Redmond. Then SQL Server bırakma OrdersTable.

Denediği SQL kodu doğru olduğu sürece, izinsiz programsal olarak algılanamaz.Bu nedenle, tüm kullanıcı giriş ve dikkatle kullanmakta olduğunuz sunucuda oluşturulan SQL komutları yürüten gözden geçirme kodu doğrulamalısınız.Kodlama en iyi uygulamalar, bu konu aşağıdaki bölümlerde açıklanmıştır.

Tüm giriş doğrula

Her zaman kullanıcı giriş türü, Uzunluk, biçimlendirme ve aralık sınayarak doğrulayın.Kötü amaçlı bir girdi karşı önlem uygularken, uygulamanýzýn mimarisi ve dağıtım senaryoları göz önünde bulundurun.Güvenli bir ortamda çalışacak biçimde tasarlanan programlar için güvenli olmayan bir ortamda kopyalanacağını unutmayın.Aşağıdaki öneriler, en iyi düşünülmesi gereken:

  • Boyutu, türü ve uygulamanız tarafından alınan veri içeriği hakkında hiçbir varsayımlar olun.Örneğin, aşağıdaki değerlendirme yapmalısınız:

    • Errant veya kötü niyetli bir kullanıcı, uygulamanız, bir posta kodu burada umuyor MPEG 10 megabaytlık dosya girerse, uygulamanızın nasıl davranacaktır?

    • Nasıl bir DROP tablo deyim, bir metin alanına katıştırılır, uygulamanızın davranacaktır?

  • Giriş boyut ve veri türünü sınamak ve uygun Sınırları zorla.Kasıtlı arabellek taşması engelleyebilirsiniz.

  • Dize değişkenleri içeriğini sınamak ve beklenen değerleri kabul edin.Ikili veri, çıkış sıralarını ve açıklama karakterleri içeren girişler ret et.Bu komut dosyası ekleme engellemenize yardımcı olabilir ve bazı arabellek taşması davetsiz girişlere karşı koruyabilirsiniz.

  • Bunu girildiği gibi XML belgeleriyle çalışırken, tüm veri, şemayla doğrulayın.

  • Hiçbir zaman oluþturma Transact-SQL doğrudan kullanıcı girdisi deyimlerinden.

  • Saklı yordamlar, kullanıcı girdisi doğrulamak için kullanın.

  • Multitiered ortamlarında, tüm veri giriş için güvenilir bir bölgeden önce doğrulanması gerektiğini.Veri doğrulama işlemi vermeyen reddetti ve bu için bir önceki bağlayıcılı bir hata döndürdü.

  • Doğrulama çok katmanlı uygular.Belirlenen saldırganlara karşı etkisiz casually kötü amaçlı kullanıcılara karşı önlemler olabilir.Kullanıcı arabirim ve burada, bir güven sınırını geçiyor tüm izleyen nokta girdisi doğrulamak iyi bir uygulamadır.

    Örneğin, bir istemci tarafı uygulama veri doğrulama, basit bir komut dosyası ekleme engelleyebilirsiniz.Sonraki bağlayıcı, giriş önceden doğrulandı varsayar, ancak bir istemci atlayabilir herhangi bir kötü amaçlı kullanıcı bir sistemde sınırsız erişiminiz.

  • Hiçbir zaman değil doğrulanacağını kullanıcı girişi bağlamak.Dize birleştirme girişi için komut dosyası ekleme birincil noktasıdır.

  • Içinden dosya adlarının oluşturulması alanları aşağıdaki dizelerden kabul: AUX, $, COM1 ile COM8 CON, CONFIG $ LPT8, NUL ve PRN, LPT1 SAAT.

Yapabilirsiniz, aşağıdaki karakterleri içeren bir giriş ret et.

Giriş karakteri

Transact-SQL'DE anlamına gelir.

;

Sınırlayıcı sorgula.

'

Verileri dize sınırlayıcı karakter.

--

Açıklama sınırlayıcısı.

/* ...*/

Açıklama sınırlayıcı.Metin arasında / * ve * / sunucu tarafından değerlendirilir.

xp_

Katalog genişletilmiş saklı yordamlar, adının başında aşağıdaki gibi kullanılır xp_cmdshell.

Tür-güvenli SQL parametreleri kullanın.

The Parameters koleksiyon in SQL Server provides tür denetimi and length validation. Kullanıp kullanmadığımı Parametreler koleksiyon, giriş olarak bir hazır bilgi değeri yerine yürütülebilir kod olarak kabul edilir.Kullanarak bir ek yararı Parametreler koleksiyon türü ve uzunluğu zorlayabilir olduğunu denetler.Değer aralık dışında bir özel durum tetikler.Aşağıdaki kod parçası kullanarak gösterir Parametreler koleksiyon:

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

Bu örnekte, @au\_id parametre olarak bir hazır bilgi değeri yerine yürütülebilir kod olarak kabul edilir. Bu değer türü ve uzunluk da kontrol edilir.Değeri @au\_id uyumlu olmayan belirtilen türü ve uzunluğu kısıtlamaları bir özel durum.

Parametreli hale getirilmiş bir giriş ile Saklý Yordamlarý Kullanma

Filtre uygulanmamış bir giriş kullandıkları saklı yordamlar SQL ekleme için açık olabilir.Örneğin, aşağıdaki kodu etkilenir:

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

Saklı yordamlar kullanırsanız, parametreleri kendi giriş olarak kullanmanız gerekir.

Parameters derlemesine dinamik SQL ile kullanın...

Saklı yordamlar kullanamazsanız, Parametreler, aşağıdaki kod örneğinde gösterildiği gibi kullanmaya devam edebilirsiniz:

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;

Giriş için süzme

Giriş için süzme de çıkış karakterleri kaldırarak, SQL ekleme karşı koruma yararlı olabilir.Ancak çok sayıda sorunlara neden karakterleri nedeniyle, bu güvenilir bir kapsamlı savunma değil.Aşağıdaki örnek, karakter dize sınırlayıcı için arama yapar.

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

Yan tümceleri

Bir LIKE yan tümcesinin kullanıyorsanız, joker karakterler hala konulmalıdır olduğunu not alın:

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

Kod için SQL ınjection gözden geçirme

yürütmek, EXEC, çağıran tüm kodu gözden geçirmelisiniz veya Sp_executesql.Bu ifadeyi içeren yordamlar belirlemenize yardımcı olması için aşağıdakine benzer bir sorgu kullanın.Bu sorgu, yürütmek veya EXEC sözcükleri sonra 1, 2, 3 veya 4 boşluk denetler.

SELECT object_Name(id) FROM syscomments

WHERE UPPER(text) LIKE '%EXECUTE (%'

OR UPPER(text) LIKE '%EXECUTE  (%'

OR UPPER(text) LIKE '%EXECUTE   (%'

OR UPPER(text) LIKE '%EXECUTE    (%'

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

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

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

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

OR UPPER(text) LIKE '%SP_EXECUTESQL%'

Parametreler QUOTENAME() ve REPLACE() kaydırma

Her seçili saklı yordam, doğrulamak, dinamik kullanılan tüm değişkenler Transact-SQL doğru işlenir. Saklı yordam giriş parametrelerinden gelir veya tablodan okunan veri QUOTENAME() veya REPLACE() alınmış.Anımsamak değeri @ değişken QUOTENAME() için geçirilen olansysnameve bir en fazla 128 karakter uzunluğunu içerir.

@ değişken

Önerilen sarmalayıcı

Bir güvenliği sağlanabilir adı

quotename)@ değişken)

≤ 128 karakter dizesi

quotename)@ değişkeni '' '')

Dize > 128 karakter

(DEĞİŞTİRİN.@ değişken, '' '' '' '' '')

Bu yöntemi kullandığınızda, bir küme deyim aşağıdaki şekilde gözden geçirilebilir:

--Before:

SET @temp = N'select * from authors where au_lname='''

+ @au\_lname + N''''

--After:

SET @temp = N'select * from authors where au_lname='''

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

Ekleme, veri kesilmesi ile etkinleştirildi

Tüm dinamik Transact-SQL için atanan bir değişken bu değişken için ayrılmış arabellek'den büyükse, kesilir. Saklı bir yordam için beklenmedik şekilde uzun dizeleri ileterek deyim kesme zorlamak için olan bir saldırganın, sonuç olarak işleyebilirsiniz.Örneğin, aşağıdaki komut dosyası tarafından oluşturulan bir saklı yordam tarafından kesme etkinleştirilmiş ekleme savunmasızdır.

CREATE PROCEDURE sp_MySetPassword

@loginname sysname,

@old sysname,

@new sysname

AS

-- Declare variable.

-- Note that the buffer here is only 200 characters long.

DECLARE @command varchar(200)

-- Construct the dynamic Transact-SQL.

-- In the following statement, we need a total of 154 characters

-- to set the password of 'sa'.

-- 26 for UPDATE statement, 16 for WHERE clause, 4 for 'sa', and 2 for

-- quotation marks surrounded by QUOTENAME(@loginname):

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

-- But because @new is declared as a sysname, this variable can only hold

-- 128 characters.

-- We can overcome this by passing some single quotation marks in @new.

SET @command= 'update Users set password=' + QUOTENAME(@new, '''') + ' where username=' + QUOTENAME(@loginname, '''') + ' AND password = ' + QUOTENAME(@old, '''')

-- Execute the command.

EXEC (@command)

GO

154 Karakterler 128 karakter arabelleğe geçirmeden, bir saldırganın yapabilirsiniz küme için yeni bir parola sa eski parolanızı bilmeden.

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

Bu nedenle, bir komut değişkeni için büyük bir arabellek kullanın veya doğrudan dinamik yürütmek gerekir Transact-SQL yürütmek deyim içinde.

Kesme, QUOTENAME(@variable, '''') ve REPLACE() kullanıldığı

Bunlar ayrılmış alan aşarsanız QUOTENAME() ve REPLACE() tarafından döndürülen dizeleri sessizce fazlalıklar atılacak.Aşağıdaki örnekte oluşturduğunuz saklı yordam ne olmasý gösterir.

CREATE PROCEDURE sp_MySetPassword

@loginname sysname,

@old sysname,

@new sysname

AS

-- Declare variables.

DECLARE @login sysname

DECLARE @newpassword sysname

DECLARE @oldpassword sysname

DECLARE @command varchar(2000)

-- In the following statements, the data stored in temp variables

-- will be truncated because the buffer size of @login, @oldpassword,

-- and @newpassword is only 128 characters, but QUOTENAME() can return

-- up to 258 characters.

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

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

SET @newpassword = QUOTENAME(@new, '''')

-- Construct the dynamic Transact-SQL.

-- If @new contains 128 characters, then @newpassword will be '123...n

-- where n is the 127th character.

-- Because the string returned by QUOTENAME() will be truncated,

-- it can be made to look like the following statement:

-- UPDATE Users SET password ='1234...[127] WHERE username=' -- other stuff here

SET @command = 'UPDATE Users set password = ' + @newpassword

+ ' where username =' + @login + ' AND password = ' + @oldpassword;

-- Execute the command.

EXEC (@command)

GO

Bu nedenle, aşağıdaki deyim, tüm kullanıcıların parolalarını önceki kod geçildi değere ayarlar.

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

Ayrılmış arabellek alanı aşma REPLACE() kullandığınızda, dize kesme zorlayabilir.Aşağıdaki örnekte oluşturduğunuz saklı yordam ne olmasý gösterir.

CREATE PROCEDURE sp_MySetPassword

@loginname sysname,

@old sysname,

@new sysname

AS

-- Declare variables.

DECLARE @login sysname

DECLARE @newpassword sysname

DECLARE @oldpassword sysname

DECLARE @command varchar(2000)

-- In the following statements, data will be truncated because

-- the buffers allocated for @login, @oldpassword and @newpassword

-- can hold only 128 characters, but QUOTENAME() can return

-- up to 258 characters.

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

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

SET @newpassword = REPLACE(@new, '''', '''''')

-- Construct the dynamic Transact-SQL.

-- If @new contains 128 characters, @newpassword will be '123...n

-- where n is the 127th character.

-- Because the string returned by QUOTENAME() will be truncated, it

-- can be made to look like the following statement:

-- UPDATE Users SET password='1234…[127] WHERE username=' -- other stuff here

SET @command= 'update Users set password = ''' + @newpassword + ''' where username='''

+ @login + ''' AND password = ''' + @oldpassword + '''';

-- Execute the command.

EXEC (@command)

GO

Ile QUOTENAME() gibi dize kesme REPLACE() tarafından her zaman için yeterince büyük geçici değişkenler bildirerek kaçınılması.Mümkün olduğunda, QUOTENAME() veya REPLACE() doğrudan içinde dinamik çağırmalısınız Transact-SQL. Aksi durumda, gerekli arabellek boyutu gibi hesaplayabilirsiniz.Için @outbuffer = QUOTENAME(@input), boyutu @outbuffer olmalıdır 2*(len(@input)+1). When you use REPLACE() and doubling quotation marks, as in the previous example, a buffer of 2*len(@input) is enough.

Aşağıdaki hesaplama tüm servis talepleri yer almaktadır:

While len(@find_string) > 0, required buffer size =

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

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

Kesme, QUOTENAME(@variable, ']') Kullanılıyor

Kesme ortaya çıkabilecek zaman adı bir SQL Server formu kullanan ifadeler için güvenliği sağlanabilir geçirilir QUOTENAME(@variable, ']'). Aşağıdaki örnek bunu göstermektedir.

CREATE PROCEDURE sp_MyProc

@schemaname sysname,

@tablename sysname,

AS

-- Declare a variable as sysname.The variable will be 128 characters.

-- But @objectname actually must allow for 2*258+1 characters.

DECLARE @objectname sysname

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

-- Do some operations.

GO

Ne tür değerleri bitiştirme sysname, 128 karakter sayısı üst sınırı değeri alacak kadar büyük olan geçici değişkenleri kullanmanız gerekir. Olanaklıysa, QUOTENAME() doğrudan içinde dinamik arayın. Transact-SQL. Aksi durumda, önceki bölümde açıklandığı gibi gerekli arabellek boyutunu hesaplayabilir.