SQL Injection

sql Injection, kötü amaçlı kod eklendiğinde daha sonra geçirilen dizeleri bir saldırı olduğu bir örnek , SQL Server ayrıştırma ve yürütme.sql deyimlerini yapıları herhangi bir yordam ekleme güvenlik açıkları için çünkü gözden geçirilmesi gereken SQL Server olur yürütmek aldığı sözdizimsel olarak geçerli tüm sorgular.Hatta parametreli veri nitelikli ve belirlenen saldırgan tarafından yönetilebilir.

sql komutları ile birleştirilmiş ve yürütülen kullanıcı giriş değişkenlerini içine doğrudan ekleme kodunu sql Injection'ın birincil form oluşur.A doğrudan saldırı daha az zararlı kod içinde depolama için gidecek dizeler içine injects bir tablo veya meta veriler olarak.Saklı dizeleri sonradan dinamik bir sql komutu birleşir, kötü amaçlı kod çalıştırılır.

Ekleme işlemi çalışır bir metin zamanından önce sona erdirmek dize ve yeni bir komut ekleme.Eklenen komut ek olabileceği için dizedaha önce eklenmiş s yürütüldüğünde, malefactor eklenirse sonlandırır dize bir açıklama işareti "--".Yürütme saat sonraki metin yoksayılır.

Aşağıdaki komut dosyası basit bir sql Injection gösterir.Komut dosyası kullanıcı tarafından girilen dize ile birlikte sabit kodlanmış Dize bitiştirme tarafından 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, komut dosyası tarafından derlenip sorgu aşağıdakine benzer:

SELECT * FROM OrdersTable WHERE ShipCity = 'Redmond'

Ancak, kullanıcı aşağıdaki girer varsayılmaktadır:

Redmond'; drop table OrdersTable--

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

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

Noktalı virgül (;) bir sorgu sona ermesi ve başka başlangıcını gösterir.Çift tire (-), geçerli satırın kalan bir açıklama ve yoksayılmalıdır gösterir.Değiştirilmiş kodu doğru değilse, sunucu tarafından yürütülür.Zaman SQL Server işler bu deyim SQL Server tüm kayıtlar seçeneğini ilk OrdersTable burada ShipCity olan Redmond.Daha sonra SQL Server bırak OrdersTable.

sql kodu doğru olduğu sürece, izinsiz programlı olarak algılanamaz.Bu nedenle, tüm kullanıcı girişi ve dikkatli bir şekilde kullanmakta olduğunuz sunucuda yapılandırılmış sql komutları yürütür gözden geçirme kod doğrulamalısınız.Kodlama en iyi bu konuda aşağıdaki bölümlerde açıklanmıştır.

Tüm giriş doğrula

Her zaman kullanıcı giriş türü, uzunluğu, biçim ve aralık test ederek doğrulayın.Kötü amaçlı giriş karşı önlemler uygularken, uygulamanızın mimarisi ve dağıtım senaryoları düşünün.Güvenli bir ortamda çalışmak üzere tasarlanmış programlar güvenli bir ortama kopyalanabilir unutmayın.Aşağıdaki öneriler en iyi düşünülmesi gereken:

  • Boyut, tür veya uygulamanız tarafından alınan veri içeriği hakkında hiçbir varsayımlar yapmak.Örneğin, aşağıdaki değerlendirme yapmanız gerekir:

    • Yalıtılarak veya kötü amaçlı bir kullanıcı, burada bir posta kodu uygulamanız beklediği bir 10 megabayt mpeg dosyası girerse, uygulamanızın nasıl davranacaktır?

    • Nasıl uygulamanızın davranırlar drop table deyim içinde bir metin katıştırılmışsa alan?

  • Giriş boyutu ve veri türünü sınamak ve uygun sınırlarını zorlamak.Bu kasıtlı Arabellek taşmaları önlemek yardımcı olabilir.

  • dize değişkenlerinin içeriğini test ve beklenen değerleri kabul eder.İkili veri, çıkış sıralarını ve yorum karakterleri içeren girişler reddet.Bu komut dosyası Sızdırma önlemeye yardımcı olabilir ve bazı arabellek taşması vektörlerine karşı koruma sağlayabilir.

  • xml belgeleri ile çalışırken, girildiği gibi şema karşı tüm verileri doğrulayın.

  • Hiçbir zaman yapı Transact-SQL deyimlerinden doğrudan kullanıcı girdi.

  • Kullanıcı girdisi doğrulamak için saklı yordamları kullanın.

  • Çok katmanlı ortamlarda, güvenilir bölgeye giriş önce tüm verilerin doğrulanması gerekir.Veri doğrulama işleminden geçmesi reddedilen ve bir hata için bir önceki katmanı döndürülmelidir.

  • Birden çok katman doğrulama uygular.Kullanıcının kötü amaçlı kullanıcılara karşı önlemler belirlenmiş yapılan saldırılara karşı etkisiz olabilir.Kullanıcı arabirim ve burada da bir güven sınırını geçiyor hiç izleyen noktaları girdisini doğrulamak iyi bir uygulamadır.

    Örneğin, bir istemci uygulamasında veri doğrulama basit komut dosyası eklenmesine engel olabilir.Sonraki katman kendi giriş önceden doğrulandı varsayar, ancak bir istemci atlayabilir herhangi bir kötü amaçlı kullanıcı sisteme sınırsız erişimi vardır.

  • Hiçbir zaman bir arada değil doğrulanmış kullanıcı girişi.Dize birleştirme birincil komut dosyası Sızdırma için giriş noktasıdır.

  • Dosya adları oluşturulabilecek alanları aşağıdaki dizeleri kabul et: aux, $, LPT1 LPT8, nul ve prn-$, COM1 COM8 con, CONFIG ile saat.

Aşağıdaki karakterleri içeren giriş yapabilirsiniz, Reddet.

Giriş karakteri

Transact-SQL anlamı

;

Sınırlayıcı sorgu.

'

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

--

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

/* ...*/

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

xp_

Katalog genişletilmiş saklı yordamlar adı başlangıcında gibi kullanılan xp_cmdshell.

Tür-güvenli sql parametreleri kullanın

The Parameters collection in SQL Server provides type checking and length validation.Kullanırsanız, parametreleri koleksiyon, giriş yürütülebilir kod olarak yerine, hazır bilgi değeri olarak işlem görür.Kullanarak ek bir yararı parametreleri türü ve uzunluğu zorlayabilir koleksiyon denetler.Dışındaki değerleri aralık bir özel durum tetikleyecek.Aşağıdaki kod parçası gösterir kullanarak parametreleri 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 parametresi yürütülebilir kod olarak yerine, hazır bilgi değeri olarak işlem görürBu değer türü ve uzunluğu için denetlenir.Varsa değeri @au_id uymak belirtilen türü ve uzunluğu sınırlamaları, bir özel durum.

Parametreli giriş ile saklı yordamları kullanma

Filtre uygulanmamış giriş kullandıkları saklı yordamlar sql Injection olasılığınız olabilir.Örneğin, aşağıdaki kod etkilenir:

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

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

Parameters derlemesi ile dinamik sql kullanın

Saklı yordamları kullanamazsını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ş filtresi

Giriş filtresi de çıkış karakterleri kaldırarak sql Injection karşı korumalarına yardımcı olabilir.Ancak çok sayıda sorun oluşturabileceği karakterleri nedeniyle, bu güvenilir bir savunma değil.Aşağıdaki örnek, karakter dize sınırlayıcı için arar.

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

GİBİ yan tümceleri

LIKE yan tümce tümce kullanıyorsanız, joker karakterler hala konulmalıdır olduğunu unutmayın:

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

sql Injection için kod gözden geçirme

execute, exec, çağıran tüm kodu gözden geçirmeniz gereken veya sp_executesql.Bu ifadeler içeren yordamları tanımlamanıza yardımcı olması için aşağıdakine benzer sorguları kullanabilirsiniz.Bu sorgu yürütme ya da exec sözcüğü sonra 1, 2, 3 veya 4 boşlukları 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%'

Parametreleri quotename() ve replace() ile kaydırma

Her seçili saklı yordam, emin olun dinamik kullanılan tüm değişkenler Transact-SQL doğru şekilde işlenir.Saklı yordam giriş parametrelerinden gelir veya karşı okunur verileri bir tablo quotename() ya da replace() sarılan.Unutmayın değeri @ değişkeni için geçirilen quotename() ise sysname, ve en fazla 128 karakter uzunlukta.

@ değişkeni

Önerilen sarıcı

Bir güvenliği sağlanabilir adı

quotename (@ değişkeni)

≤ 128 karakter dizesi

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

Dize, > 128 karakter

Değiştir (@ değişkeni,'' '', '''' '')

Bu tekniği kullandığınızda, bir set 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''''

Veri kesilmesi tarafından etkin ekleme

Tüm dinamik Transact-SQL için atanmış bir değişken bu değişkeni. için ayrılmış arabellek büyükse kesilecekBir saklı yordam için beklenmedik bir şekilde uzun dizeleri aktararak deyim kesilme zorla olanağına sahip olan bir saldırganın, sonucu işleyebilirsiniz.Örneğin, aşağıdaki komut dosyası tarafından oluşturulan bir saklı yordam tarafından kesme etkin yerleştirmeye karşı savunmasız olur.

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ğine geçirerek, saldırgan olabilir küme için yeni bir parola sa olmadan bilmek eski parola.

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

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

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

Bunlar tahsis edilen alan aşarsa, quotename() ve replace() tarafından döndürülen dizeleri sessizce kesilecek.Aşağıdaki örnekte oluşturulan saklı yordam gerçekleşebilir ne 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 kodda geçirilen değere küme.

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

replace() kullandığınızda ayrılmış arabellek alanı aşan dize kesilme zorlayabilirsiniz.Aşağıdaki örnekte oluşturulan saklı yordam gerçekleşebilir ne 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

İle quotename() gibi dize kesilme replace() tarafından tüm durumlar için yeterince geçici değişkenler bildirerek önlenebilir.Mümkün olduğunda, quotename() veya replace() doğrudan dinamik çağırmalıdır Transact-SQL.Aksi takdirde, gerekli hesaplayabilirsiniz arabellek boyutu gibi.İçin @outbuffer = QUOTENAME(@input), boyutunu @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 durumlarda kapsar:

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ılan

Kesme meydana gelebilir, adını bir SQL Server güvenliği sağlanabilir geçirilir ifadeleri formu kullanmak için QUOTENAME(@variable, ']').Bunu aşağıdaki örnekte gösterilmektedir.

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 zaman size bitiştirme türünün değerlerini sysname, geçici değişkenler yeterince büyük değeri başına en çok 128 karakter tutmak için kullanılması gerekenMümkünse, quotename() doğrudan dinamik çağrı Transact-SQL.Aksi takdirde, bir önceki bölümde de açıklandığı gibi gerekli arabellek boyutu hesaplayabilirsiniz.