我完全意識到清理SQL查詢的正確做法是對它們進行參數化。替換'轉義字符後T-SQL的安全性如何?
我在很多預先存在的代碼上工作,其中衛生措施是用動態字符串替換所有'
的場合與''
。我想弄清楚我應該如何擔心。
事情是這樣的:這個代碼運行在T-SQL專門(SQL服務器2008 R2及更高版本),而且據我所知,'
是T-SQL的只有轉義字符。
那麼,你將如何執行注入攻擊闖過上述措施?即在T-SQL上,這種非常「幼稚」的衛生方式確實非常穩固,因爲它看起來像?
我完全意識到清理SQL查詢的正確做法是對它們進行參數化。替換'轉義字符後T-SQL的安全性如何?
我在很多預先存在的代碼上工作,其中衛生措施是用動態字符串替換所有'
的場合與''
。我想弄清楚我應該如何擔心。
事情是這樣的:這個代碼運行在T-SQL專門(SQL服務器2008 R2及更高版本),而且據我所知,'
是T-SQL的只有轉義字符。
那麼,你將如何執行注入攻擊闖過上述措施?即在T-SQL上,這種非常「幼稚」的衛生方式確實非常穩固,因爲它看起來像?
是的,單引號是唯一的轉義字符,所以你主要是,主要是,但並不完全正確。
使用參數,而最好的,大多隻是做了'
到''
更換你正在做手工。但是,他們也強制執行最大字符串長度。當然,如果我們談論的是非字符串參數,他們會有強制執行數據類型的好處(例如,'
不需要轉義爲數字,日期/時間等類型,因爲它無效他們開始)。
您可能仍然留下的問題是SQL注入的一個子集,稱爲SQL截斷。這個想法是強制動態sql的一部分離開字符串的末尾。我不確定這種情況在實際中會發生多少,但根據構建動態SQL的方式和位置,您需要確保持有要執行的動態SQL的變量足夠大以將靜態塊保存在你的代碼加上所有的變量,假設它們以最大長度提交。
這是來自MSDN Magazine,New SQL Truncation Attacks And How To Avoid Them的文章,它顯示了常規SQL注入以及SQL截斷。您將在文章中看到,爲避免SQL注入,他們大多隻是執行REPLACE(@variable, '''', '''''')
方法,但在某些情況下也會顯示使用QUOTENAME(@variable, '[')
。
EDIT(2015年1月20日):這裏是一個很好的資源,雖然沒有具體到SQL Server,詳細描述各種類型的SQL注入的:https://www.owasp.org/index.php/Testing_for_SQL_Injection_(OTG-INPVAL-005)
下面的文章涉及上述一個。這一個特定於SQL Server,但在整體安全性方面更一般。有幾個與SQL注入相關的部分:
https://www.owasp.org/index.php/Testing_for_SQL_Server
謝謝!我正在尋找的答案的類型。 – piaste 2014-12-02 19:12:15
(刀片圍繞打破消毒和逃離這裏的危險言論。見marc_s的評論。)
你在這裏提出什麼是微軟的SQL Server管理對象(SMO)使用同樣的方法。這些都是.NET DLL,可以使用反編譯器進行檢查。例如:
internal static string MakeSqlString(string value)
{
StringBuilder builder = new StringBuilder();
builder.Append("N'");
builder.Append(EscapeString(value, '\''));
builder.Append("'");
return builder.ToString();
}
public static string EscapeString(string value, char escapeCharacter)
{
StringBuilder builder = new StringBuilder();
foreach (char ch in value)
{
builder.Append(ch);
if (escapeCharacter == ch)
{
builder.Append(ch);
}
}
return builder.ToString();
}
因此根據微軟的是,簡單地做一個Replace("'", "''")
就足夠了。我確定這不僅僅是實習生代碼,而是爲了安全而進行審計。由於SDL,他們總是這樣做。
還請注意,這段代碼似乎是由使用Unicode(見N
前綴)工作。顯然,這也是Unicode安全的。
在一個比較主觀的注:我不逃避T-SQL字符串文字就是這樣的,如果我不得不這樣做。我相信這種方法。
這是在.NET
我現在發現的問題是標籤的TSQL而不是.NET
馬克暗示,你可以用Unicode或十六進制表示欺騙它。 我測試過,無論是unicode還是hex都在.NET中愚弄它。
至於用適當數量的撇號愚弄它。 如果你總是用兩個替換一個,我看不出一個合適的數字如何欺騙它。
u0027和x0027是撇號,它是有兩個單引號
2018年至2019年更換的左,右的報價和SQL只是它們當作文字
string badString = "sql inject \' bad stuff here hex \x0027 other bad stuff unicode \u0027 other bad stuff left \u2018 other bad stuff right \u2019 other bad stuff";
System.Diagnostics.Debug.WriteLine(badString);
System.Diagnostics.Debug.WriteLine(SQLclean(badString));
}
public string SQLclean(string s)
{
string cleanString = s.Replace("\'", "\'\'");
return "N\'" + cleanString + "\'";
}
我認爲參數是一個更好的做法
可以用其十六進制表示法或其Unicode表示法替換單引號字符,或者可以通過預期該行爲並使用適當數量的單引號,這樣你的「衛生」就完全失敗了...... **認真**:不要這樣做。 ***永遠不會*** - 使用parmaeters - ***總是*** – 2014-12-02 09:00:59
@marc_s請寫一個插入語句,插入1000行50個字段。如果你能做到這一點(提示:你不能),那麼我稱這是一個很好的評論。否則:無知。參數的數量是有限的,有時使用另一種方法是很好的情況。 – TomTom 2014-12-02 15:38:02
如果你正在做的TomTom使用SQLBulkCopy - marc_s是正確的,至少有關使用參數 – Swomble 2014-12-02 15:42:00