2014-09-03 62 views
2

我有兩個問題 1.我有一個列名字符串,它是列名。我如何在SQL查詢中使用它? 2.該方法是否容易出現SQL注入?用字符串列名查詢SQL表名

這就是我現在所擁有的,

List<string> Columnnames = new List<string>(); 

cmd = new SqlCommand("Select "+Columnnames+" from test"); 
+0

列名從哪裏來?用戶輸入?爲什麼你需要它是動態的? – 2014-09-03 10:42:28

+0

真正防止SQL注入的唯一方法是將所有內容都視爲在SQL本身中查看或存儲過程,並具有非常好的觸發器和驗證。 – Franck 2014-09-03 10:44:53

+0

是的,它是用戶輸入來自具有所有列名的列表框。 – Mike 2014-09-03 10:45:25

回答

1

回答您的問題:

問題1 - 你的代碼更改爲類似:

List<string> Columnnames = new List<string>(); 

// Code that populates Columnnames here 

cmd = new SqlCommand("Select " + string.Join(",", Columnnames) + " from test"); 

問題2 - 取決於你如何填充Columnnames。如果這是從網上輸入填充,那麼是的。

+0

謝謝你的作品。列名填充在具有所有列名的列表框中的用戶輸入上。是否仍有機會進行SQL注入? – Mike 2014-09-03 10:52:03

+2

@ user3272054這裏的UI是什麼?網站的? WinForm的? WPF?如果答案是「網絡」,那麼答案是「是的,絕對的,簡單的」。如果答案是「winform」/「WPF」,那麼「有點可能是的,但他們必須真的努力工作,而且直接去sql server會容易些,因爲他們可能有訪問權限」 – 2014-09-03 10:57:54

+0

@MarcGravell:謝謝。它是winforms。 – Mike 2014-09-03 10:59:18

0

可以的Columnnames列表轉換爲逗號分隔的列值。就像這樣:

string columns = Columnnames.Aggregate((x,y) => x + "," + y); 
cmd = new SqlCommand("Select "+columns+" from test"); 

這種方法很容易受到SQL注入有人可以輕鬆地發送列名像column ;drop database yourDB所以它是一個壞主意。

0

首先檢查Columnames是否有任何值。 其次做一個函數來創建類似於dus columna,columnb

SqlCommend應該看起來像這樣select columna,columb from test;

0

您應該將列名連接到查詢,以便每個列名用下一個逗號分隔,例如, (僞)

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注入。

1

如果列名來自外部源,那麼是的,您必須將它們連接到字符串中。理想情況下,您應該使用[/],但只允許使用空格等列名 - 它不會更改有關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(); 
+0

這確實有幫助!再次感謝!! – Mike 2014-09-03 10:59:55