谷歌變成了各種各樣的消毒Web訪問查詢的討論,但我沒有找到任何解決什麼,我關心的是:在C#程序消毒SQL數據
消毒用戶輸入數據。這必須通過可逆轉化來完成,而不是通過去除。作爲問題的一個簡單例子,我不想破壞愛爾蘭人的名字。
什麼是最好的方法,是否有任何庫函數呢?
谷歌變成了各種各樣的消毒Web訪問查詢的討論,但我沒有找到任何解決什麼,我關心的是:在C#程序消毒SQL數據
消毒用戶輸入數據。這必須通過可逆轉化來完成,而不是通過去除。作爲問題的一個簡單例子,我不想破壞愛爾蘭人的名字。
什麼是最好的方法,是否有任何庫函數呢?
這取決於您使用的SQL數據庫。例如,如果你想在MySQL中使用單引號,你需要使用一個反斜槓Dangerous:'
和一個逃脫的轉義字符:\'
。對於MS-SQL,情況完全不同,危險:'
轉義:''
。當您以這種方式轉義數據時,不會刪除任何內容,它是一種表示控制字符的方式,如字面形式的引號。
下面是使用MS-SQL和C#參數化查詢,從Docs採取的一個例子:
private static void UpdateDemographics(Int32 customerID,
string demoXml, string connectionString)
{
// Update the demographics for a store, which is stored
// in an xml column.
string commandText = "UPDATE Sales.Store SET Demographics = @demographics "
+ "WHERE CustomerID = @ID;";
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand command = new SqlCommand(commandText, connection);
command.Parameters.Add("@ID", SqlDbType.Int);
command.Parameters["@ID"].Value = customerID;
// Use AddWithValue to assign Demographics.
// SQL Server will implicitly convert strings into XML.
command.Parameters.AddWithValue("@demographics", demoXml);
try
{
connection.Open();
Int32 rowsAffected = command.ExecuteNonQuery();
Console.WriteLine("RowsAffected: {0}", rowsAffected);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
對於MySQL我不知道,你可以使用參數化查詢庫。您應該使用mysql_real_escape_string()或者任意使用此功能。:
public static string MySqlEscape(this string usString)
{
if (usString == null)
{
return null;
}
// SQL Encoding for MySQL Recommended here:
// http://au.php.net/manual/en/function.mysql-real-escape-string.php
// it escapes \r, \n, \x00, \x1a, baskslash, single quotes, and double quotes
return Regex.Replace(usString, @"[\r\n\x00\x1a\\'""]", @"\$0");
}
我意識到這是一個較舊的帖子,但PHP [5.0 +]確實通過MySQLi(http://php.net/manual/en/book.mysqli.php)和PDO庫(http:///php.net/manual/en/book.pdo.php)。 – 2012-06-19 09:52:06
@Tieson T.和adodb,以及參數化查詢是最好的選擇。 – rook 2012-06-19 17:42:13
fyi,mysql_real_escape_string已被棄用 – 2013-04-22 18:29:36
使用適當構造的DAL與SQL參數對象交給存儲過程,您不必擔心這一點。實現業務對象和dal以足夠抽象用戶輸入,以使其不作爲SQL執行,而是作爲值進行識別。示例很有趣:
public class SomeDal
{
public void CreateUser(User userToBeCreated)
{
using(connection bla bla)
{
// create and execute a command object filling its parameters with data from the User object
}
}
}
public class User
{
public string Name { get; set; }
...
}
public class UserBL
{
public CreateUser(User userToBeCreated)
{
SomeDal myDal = new SomeDal();
myDal.CreateUser(userToBeCreated);
}
}
public class SomeUI
{
public void HandleCreateClick(object sender, e ButtonClickEventArgs)
{
User userToBeCreated = new User() { Name = txtName.Text };
UserBL userBl = new UserBL();
userBl.CreateUser(userToBeCreated);
}
}
我看到parematerized命令是要走的路,但您的示例代碼與它們無關! – 2010-08-13 20:26:33
@Loren Pechtel:評論說要使用它們,而且你希望你的用戶輸入填充一個像User的業務對象,它充當傳輸到dal的業務對象,它創建命令和參數。這種抽象將數據庫中的用戶與安全性分離,因爲你可以創建一個UserValidator和其他類似的東西,使得他們的輸入不僅可以從SQL注入中安全使用,而且可以避免無效值。 – 2010-08-13 20:31:34
我同意你需要一個檢查有效性的層次,但這與保持系統免於奧尼爾先生的窒息是分開的。 – 2010-08-14 04:51:36
是否將可能包含撇號的數據傳遞給SQL查詢?如果您使用SQL Parameter對象,那應該不成問題。你會得到你的消毒,並且你的數據中的任何重要字符都應該被正確地轉義。 – 2010-08-13 17:53:02
同意的參數化查詢是可行的方法。 – driis 2010-08-13 17:57:53
我只通過業務邏輯生成SQL查詢。 – Jeroen 2010-08-13 18:11:45