我有兩個問題 1.我有一個列名字符串,它是列名。我如何在SQL查詢中使用它? 2.該方法是否容易出現SQL注入?用字符串列名查詢SQL表名
這就是我現在所擁有的,
List<string> Columnnames = new List<string>();
cmd = new SqlCommand("Select "+Columnnames+" from test");
我有兩個問題 1.我有一個列名字符串,它是列名。我如何在SQL查詢中使用它? 2.該方法是否容易出現SQL注入?用字符串列名查詢SQL表名
這就是我現在所擁有的,
List<string> Columnnames = new List<string>();
cmd = new SqlCommand("Select "+Columnnames+" from test");
回答您的問題:
問題1 - 你的代碼更改爲類似:
List<string> Columnnames = new List<string>();
// Code that populates Columnnames here
cmd = new SqlCommand("Select " + string.Join(",", Columnnames) + " from test");
問題2 - 取決於你如何填充Columnnames
。如果這是從網上輸入填充,那麼是的。
謝謝你的作品。列名填充在具有所有列名的列表框中的用戶輸入上。是否仍有機會進行SQL注入? – Mike 2014-09-03 10:52:03
@ user3272054這裏的UI是什麼?網站的? WinForm的? WPF?如果答案是「網絡」,那麼答案是「是的,絕對的,簡單的」。如果答案是「winform」/「WPF」,那麼「有點可能是的,但他們必須真的努力工作,而且直接去sql server會容易些,因爲他們可能有訪問權限」 – 2014-09-03 10:57:54
@MarcGravell:謝謝。它是winforms。 – Mike 2014-09-03 10:59:18
可以的Columnnames
列表轉換爲逗號分隔的列值。就像這樣:
string columns = Columnnames.Aggregate((x,y) => x + "," + y);
cmd = new SqlCommand("Select "+columns+" from test");
這種方法很容易受到SQL注入有人可以輕鬆地發送列名像column ;drop database yourDB
所以它是一個壞主意。
首先檢查Columnames是否有任何值。 其次做一個函數來創建類似於dus columna,columnb
SqlCommend應該看起來像這樣select columna,columb from test;
您應該將列名連接到查詢,以便每個列名用下一個逗號分隔,例如, (僞)
define sql = "SELECT "
for columnName in columnNames:
concatenate sql,columnName
if columnName is not last:
concatenate sql,","
end if
end for
concatenate sql," FROM test"
漏洞取決於列名的來源。如果你有內部不變的列名列表,那麼沒有風險,但是如果它們來自外部源,比如使用應用程序的用戶,那麼它肯定會傾向於SQL注入。
如果列名來自外部源,那麼是的,您必須將它們連接到字符串中。理想情況下,您應該使用[
/]
,但只允許使用空格等列名 - 它不會更改有關SQL注入的任何內容,而且:允許用戶指定列名將是SQL注入風險,除非您先列出它們。所以也許:
if(Columnnames.Count == 0) throw new ArgumentException(
"You need to specify at least one column");
var sql = new StringBuilder("select ");
bool first = true;
foreach(var name in Columnnames) {
if(!IsKnownColumnName(name)) { // <=== very important test
throw new ArgumentException("Invalid column name: " + name);
}
sql.Append(first ? "[" : ",[").Append(name).Append("]");
first = false;
}
sql.Append(" from test");
...
cmd.CommandText = sql.ToString();
這確實有幫助!再次感謝!! – Mike 2014-09-03 10:59:55
列名從哪裏來?用戶輸入?爲什麼你需要它是動態的? – 2014-09-03 10:42:28
真正防止SQL注入的唯一方法是將所有內容都視爲在SQL本身中查看或存儲過程,並具有非常好的觸發器和驗證。 – Franck 2014-09-03 10:44:53
是的,它是用戶輸入來自具有所有列名的列表框。 – Mike 2014-09-03 10:45:25